国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > JavaScript > 正文

詳解node.js進行web開發的操作方法

2024-05-06 15:46:04
字體:
來源:轉載
供稿:網友

學習程序是個很漫長的過程,而錯新技術頻道剛好是一個很好的學習平臺,本文是小編為大家帶來的詳解node.js進行web開發的操作方法,相信本文的知識對大家有一定的意義。

1.express框架安裝

1)在node命令行模式下輸入以下命令

npm install -g express

該命令在全局環境下安裝express框架,在安裝完這一步之后,并不能直接使用express命令來生成express項目,需要再安裝一個express項目生成器,在express2.X的版本中是不需要的,express4.X版本之后將項目生成器和express本身分離了出來,如果不安裝express-generator這個生成器就使用express命令來生成項目,會遇到報express不是內部或外部命令這個錯誤,這是需要注意的地方,nodejs web開發指南原書中是沒有安裝express-generator這一步的。

2)安裝express-generator

npm install -g express-generator

3)生成一個項目

cd ..mkdir microblogcd microblogexpress micorblog

這里隨意在硬盤某個目錄下創建一個microblog的文件夾,進入該文件夾,然后使用express microblog命令創建了一個microblog的express項目。

生成結構如下:

其中app.js是項目入口文件,package.json是npm 包管理文件,bin文件夾里面的www.js放一些全局配置項以及命令行配置等。public 文件夾是用來存放項目靜態文件目錄如js,css以及圖片,routes文件夾是用來存放路由監聽的代碼相關文件。views文件夾用來存放模板文件,這里需要注意的是express4.X使用jade作為項目的默認模板引擎,而在原書中是使用ejs作為模板引擎的,所以這里默認生成的是jade文件。無可否認ejs是要簡單些,但是原理都是一樣的,我們使用jade作為開發的模板引擎。

4)啟動項目并查看

cd microblognpm installnpm start

進入到microblog文件夾,安裝項目所需相關模塊(根據pacakge.json文件),然后啟動項目,這時候打開瀏覽器查看項目輸入地址localhost:3000,結果如下說明一切正常,

到目前為止,我們已經擁有了一個在瀏覽器中運行的web項目雛形。下面進行開發,原書中的微博項目的主要功能是用戶能夠注冊登錄,權限控制并讓用戶發布微博在用戶個人主頁和項目首頁分別顯示,這些功能完整版代碼會提供,由于篇幅原因,這里以用戶注冊登錄模塊來說明如何進行一個完整流程的web開發。

2.頁面布局

依照web開發流程,我們首先來構建一個項目主頁,項目主頁是由布局文件layout.jade和內容文件index.jade組成,關于的jade的學習,這里提供兩個地址,對于以前使用過類似模板引擎如smarty,razor等的,可以看看文檔就能夠上手做了,基本原理都是大同小異。

打開views文件,將layout.jade文件代碼改寫如下:

doctype htmlhtml head  title= title  link(rel='stylesheet', href='/stylesheets/style.css') body   nav.header     ul.list       li.logo         a(href='/') Microblog       li         a(href='/') 首頁       li         a(href='/login') 登錄       li         a(href='/reg') 注冊    div.container      block content      hr      footer.footer        p          a() myzhibie          | @2015

需要注意父級元素和子元素的換行之間縮進,jade是利用縮進來區別代碼層級的。

首頁內容文件index.jade

extends layoutblock content  main.main    section.intro      if message        h3.indexmes #{message}      //如果用戶登錄或者注冊成功并且沒有在登錄狀態下點擊注冊或者登錄      if success&&user        h1.welcome #{success},歡迎 #{user} 來到 Microblog      else if !success&&user        h1.welcome 歡迎 #{user} 來到 Microblog      else        h1.welcome 歡迎來到 Microblog      h3.tech Microblog是一個基于Node.js,使用express4.12.1,jade1.9.2以及MongoDB搭建起來的微博系統,是對Node.js開發指南一書中教學項目的重構。      p.btnlist        if user          a.login(href='/logout') 退出          a.userlink(href='/users/#{user}') 發表文章        else          a.login(href='/login') 登錄          a.register(href='/reg') 立即注冊    section.show      each val in posts        article.col          h3.author #{val.user}說          p            | #{val.post}

首頁內容是繼承了模板文件layout.jade.原書中使用的bootstrap來構建頁面的css布局和樣式,這里我自己手寫了一個仿bootstrap風格的布局樣式,沒有應用bootstrap,style.css文件如下:

body { padding: 50px; font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;}html,body,ul,p,hr,h3{  margin:0;  padding: 0;}a { color: #00B7FF;}.header{  background:#337aB7;  width: 100%;  height: 60px;  color: #fff;  font-size: 22px;  overflow: hidden;}.list{  line-height: 60px;}.navigation{  overflow: hidden;}.list li{  list-style: none;  float: left;  display: inline-block;  margin-left: 20px;  margin-right: 20px;}.list li a{  text-decoration: none;  color: #fff;}.list li a:hover{}.list li:not(:first-child) a:hover{  font-size: 26px;  color: #F5F5F5;}.logo{  font-size: 26px;  font-weight: 700;}.container{  min-height: 500px;  text-align: center;  width: 100%;}.footer{  width: 100%;  height: 50px;  font-size: 22px;  background:#F5F5F5 ;  line-height: 50px;}.footer a{  color:#337aB7;  text-decoration: none;}.main{  color: #000000;  width: 96%;  margin: 30px auto;}.intro{  width: 100%;  margin:0 auto;  border-radius: 5px;  height: 300px;  background:#F5F5F5 ;}.userintro{  width: 100%;  margin:0 auto;  border-radius: 5px;  height: 200px;  background:#F5F5F5 ;}.welcome{  padding-top: 50px;  padding-left:50px;  font-size: 50px;  text-align: left;  padding-bottom: 0;  margin: 0;}.tech{  text-align: left;  padding-left:50px;  margin: 0;}.show{  overflow: hidden;  width: 100%;}.show li{  text-align: left;  font-size: 18px;}.col{  display: inline-block;  float: left;  width: 32%;  height: 100px;  overflow: hidden;  padding-right: 20px;  text-align: left;  text-overflow: ellipsis;}.author{  margin-top: 10px;  margin-bottom: 3px;}.btnlist{  padding-left: 50px;  text-align: left;}.login{  display: inline-block;  padding-left: 15px;  padding-right: 15px;  height: 38px;  line-height: 40px;  background: -webkit-gradient(linear, left top, left bottom, from(#0068A6), to(#337aB7));  color: #fff;  text-align: center;  border-radius: 5px;  font-size: 20px;  font-weight: 600;  border: 1px solid #ccc;  text-decoration: none;  margin-right: 10px;}.register{  display: inline-block;  padding-left: 15px;  padding-right: 15px;  height: 38px;  line-height: 40px;  background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#F5F5F5));  color: #000;  text-align: center;  border-radius: 5px;  font-size: 20px;  font-weight: 600;  border: 1px solid #ccc;  text-decoration: none;}.field{  margin-top: 20px;  margin-left: 50px;  text-align: left;  margin-bottom: 20px;  border:none;  border-bottom: 1px solid #ccc;}.label{  font-size: 18px;  font-weight: 600;  line-height: 100%;  display: inline-block;  width: 10%;  vertical-align: middle;  text-align: right;  padding-right: 10px;}.regheader{  text-align: left;  font-size: 24px;  font-weight: 600;}.regform{  text-align: left;  padding-left: 100px;  margin-bottom: 20px;}.regform input[type='text'],input[type='password']{  width: 200px;  height: 20px;}.regform input[type='submit']{  width: 120px;  height: 30px;  color: #fff;  background:-webkit-gradient(linear, left top, left bottom, from(#0068A6), to(#337aB7));  border-radius: 5px;  font-size: 20px;}.item{  margin:20px;  width: 100%;}.mess{  font-size: 18px;  color: #E73C3C;  background: #F2DEDE;  border-radius: 5px;  width: 300px;  text-align: center;  margin-left: 100px;}.indexmes{  height: 30px;  line-height: 30px;  background: #F2DEDE;  color: #E73C3C;}.article{  width: 60%;  height: 30px;  border-radius: 3px;  border: 1px solid #A3C732;  margin-top: 5px;  font-size: 20px;}.submit{  height: 40px;  vertical-align: middle;  padding: 0;  margin-top: -5px;  margin-left: 5px;  width: 80px;  background: #A3c732;  font-size: 20px;  border: none;  border-radius: 5px;  color: #fff;}.submitform{  margin-top: 25px;  margin-left: -10px;}.userlink{  display: inline-block;  text-decoration: none;  line-height: 38px;  height: 38px;  vertical-align: middle;  padding: 0;  margin-top: -8px;  margin-left: 5px;  width: 90px;  text-align: center;  background: #A3c732;  font-size: 20px;  font-weight: 600;  border-radius: 5px;  color: #fff;  border: 1px solid #ccc;}.usertitle{  text-align: left;  padding-top: 5px;  padding-bottom: 0;  padding-left: 5px;  margin-bottom: 8px;}.usersuccess{  height: 30px;  background: #DFF0D8;  line-height: 30px;  color: #3C7668;}

這個css文件是項目中所有的css全部包含在這里,所以比較龐大。到目前為止,可以查看首頁效果如下:

首頁中的數據都是之前自己測試過程中加入的,這里主要為了查看首頁效果,可以忽略這些數據。

由于這里要演示用戶注冊登錄模塊,用戶注冊模塊的模板文件reg.jade如下:

extends layoutblock content  h3.field.regheader #{title}  form.regform(method='post')    p.mess #{message}    div.item      label.label(for='username') 用戶名      input(type='text',placeholder='輸入注冊用戶名',id='username',name='username')    div.item      label.label(for='password') 用戶密碼      input(type='password',placeholder='用戶密碼',id='password',name='password')    div.item      label.label(for='passwordconf') 重復密碼      input(type='password',placeholder='重復密碼',id='passwordconf',name='passwordconf')    div.item      label.label      input(type='submit' id='sub',name='sub' value='注冊')

用戶登陸模板login.jade如下:

extends layoutblock content  h3.field.regheader #{title}  form.regform(method='post')    p.mess #{message}    div.item      label.label(for='username') 用戶名      input(type='text',placeholder='輸入登陸用戶名',id='username',name='username')    div.item      label.label(for='password') 用戶密碼      input(type='password',placeholder='用戶密碼',id='password',name='password')    div.item      label.label      input(type='submit' id='sub',name='sub' value='登陸')

最終用戶注冊效果如下:

用戶登錄模塊和這個效果相仿,就不查看了,少了一個重復密碼的input而已。

下面我們需要編寫用戶注冊的邏輯,在編寫用戶注冊邏輯的前,用戶數據需要持久化,所以首先要安裝MongoDB數據庫在自己的機器上.

MongoDB這種nosql類型的數據庫,非常適合用戶存儲JSON對象類型的數據,有了mongoDB,就可以免去數據庫表設計部分的工作,對比以前使用的mysql,sqlserver以及oracle還是非常方便的。關于mongoDB數據庫的熟悉和學習,推薦其官網,官網詳細介紹了該數據庫的一切。英文不好可以去中文社區。同時為了使用nodejs來操作mongoDB數據庫,我們使用mongoose這個對象模型,它是將mongoDB中的一個集合映射為nodejs中的一個model,然后在該model上提供操作這個集合的一些方法,使用它就可以避免我們自己利用nodejs提供的原生操作mongoDB數據庫的語法去手寫數據庫CURD的方法,大大見曬了工作量,提高了開發效率。關于mongoose的學習,推薦去其官網,里面詳述了它的安裝,使用以及API調用情況。

解決了mongoDB安裝和操作問題,我們來對數據庫操作的model類,首先在項目路徑下建立一個db.js文件,用來連接數據庫并對數據庫進行全局配置,如下

db.js

var settings=require("./settings");var mongoose=require('mongoose');mongoose.connect("mongodb://"+settings.ip+"/"+settings.db);var db=mongoose.connection;module.exports={  "dbCon":db,  "mongoose":mongoose};

這里首先加載了配置文件settings.js文件,為了數據庫便于靈活修改,我們將某些信息存儲在配置文件中。然后加在了之前安裝的mongoose模塊,然后調用該模塊的connect方法來連接我們配置的數據庫,然后將連接以對象的形式返回供外部調用。

settings.js

module.exports={  "ip":"localhost",  "db":"microblog",  "host":27071};

MongoDB的默認端口是27071,一般可以使用默認端口即可,數據庫連接大時候可以不指定端口,數據庫名為microblog.

然后以db.js返回的數據庫連接對象為基礎,我們在項目根目錄下創建一個models文件夾,用來存放數據模型。創建一個user.js映射我們數據庫中的user集合(可以理解為user表),代碼如下:

var mongoose=require('../db').mongoose;var schema=new mongoose.Schema({  name:'string',  password:'string'});var User=mongoose.model('User',schema);module.exports=User;

這里首先獲得db.js中定義的連接對象,并以該對象為基礎構造一個Schema(架構),mogoose操作數據庫是以架構為基礎的,類似于我們其他ORM模型中屬性和方法的定義。這里我們定義了一個架構,擁有兩個屬性,name和password,都是string類型,對應用戶的用戶名和密碼。然后利用該架構去創建一個model,該model上定義了對數據集合的增刪改查等方法,不用我們自己再去定義和編寫其他代碼。在原書中這一節是利用node.js操作MongoDB數據庫的原生API去定義了一個user對象,然后在user對象上自定義了一些CRUD的方法。可以看出,直接使用Mongoose可以大大減少開發量并且擁有更好的效率和性能。

到目前為止,我們已經有了界面(view),數據模型(model),就差邏輯代碼(controller)沒有編寫了。在編寫邏輯代碼之前需要先說下express框架的特點以及它的整體運行方式。由于本人使用過一些類似的如Asp.net mvc,Yii以及thinkphp等MVC框架,使用express之后最大的感覺是這個框架夠輕量級,尤其是express4.X之后,它僅僅保留了靜態文件路徑映射模塊作為該框架本身的內置模塊,其他的功能都以中間件的形式采用require(modulename)進行引入,只有引入后才能夠使用該模塊提供的功能。

express的工作原理是客戶端發送一個request,express接到該請求,可以將它進行處理之后傳遞給其他中間件進行處理,最終處理完成之后,采用respond.end或者response.render進行頁面渲染或響應,進行頁面渲染的時候,采用參數傳遞頁面需要的數據給對應模板引擎,模板引擎收到數據然后按照自己的語法進行替換生成對應的html,最終返回給瀏覽器進行渲染。

在express中,最關鍵的部分就是路有機制,我們所有基于請求做出的響應都是對該路由進行監聽捕獲的結果。舉個例子,如果我們請求一個路徑為http://localhost:3000/user,那么必須在routes文件夾下面的路徑監聽(暫且叫做監聽吧)的js文件中編寫對該請求的響應代碼,諸如app.post('/user',function(...){...})之類的代碼,如果不存在這樣的代碼,就會報一個404錯誤,因為請求沒有得到響應,express實例不知道怎么去響應這個請求。以上就是express大致的原理和工作流程,對于它的學習,推薦去express官網直接去看文檔,講的很詳細。

現在回到用戶注冊模塊,我們注冊用戶常見的做法是注冊成功之后就默認用戶已經登錄,直接跳轉到歡迎登陸界面。在這里我們需要將用戶數據在注冊成功之后保存在session中,express框架對于session的支持是通過中間件express-session來的,使用方式依然是在npm 下安裝,然后在項目主文件中使用require加載,最后調用其提供的API,為了使用session,必須先安裝cookie的支持,這里利用cookie-parser這個中間件來為express框架提供cookie支持,它的具體使用方式可以去上面提供的地址自行查看。對于session,我們常見框架的做法是在服務器端將其存放到文件當中,由于這里我們有了MongoDB數據庫,更理想的狀態是將它存在數據庫中,這樣可以更靈活去控制。使用connect-mongo中間件可以將session存儲到mongoDB中,具體使用方式可按地址查看。

上述概念明確之后,我們在項目根目錄下的app.js(項目入口文件)中加載我們需要的中間件模塊和自定義的模塊如下:

app.js模塊加載代碼:

var express = require('express');var path = require('path');var favicon = require('serve-favicon');var logger = require('morgan');var cookieParser = require('cookie-parser');var bodyParser = require('body-parser');var routes = require('./routes/index');var users = require('./routes/users');var session = require("express-session");var MongoStore=require('connect-mongo')(session);var db = require('./db');var app = express();// view engine setupapp.set('views', path.join(__dirname, 'views'));app.set('view engine', 'jade');// uncomment after placing your favicon in /public//app.use(favicon(__dirname + '/public/favicon.ico'));app.use(logger('dev'));app.use(bodyParser.json());app.use(bodyParser.urlencoded({ extended: false }));app.use(cookieParser());app.use(express.static(path.join(__dirname, 'public')));app.use(session({  secret:"myzhibie",  store:new MongoStore({  mongooseConnection:db.dbCon  })})); app.use('/', routes); app.use('/users', users);

上述代碼就是加載各個中間件模塊并采用app.use來load這個模塊,其中上述代碼的最后一指定了將session存儲在MongoDB數據庫中,secret屬性是對session的簽名,通常是一個字符串,這是必選項,如果不寫,

是無法完成將session存儲進入數據庫的,關于該功能的更詳細介紹請查看文檔,最后兩句app.use('/',routes)和app.use('/users',users)代表對于這兩個路由的訪問處理代碼我們封裝在了routes和users模塊中,er這兩個模塊都在routes文件夾下面。

完成了模塊引入加載和一些基本的設置,現在來編寫用戶注冊的邏輯代碼,上面說到對于路徑/的訪問處理在routes模塊中,這個模塊指的就是routes文件夾下面的index.js,部分代碼如下:

var express = require('express');var crypto = require('crypto');var router = express.Router();var db=require('../db');var User=require('../models/user');var Post=require('../models/post');/* GET home page. */router.get('/', function(req, res, next) {  Post.find({},function(err,posts){    if(err){      req.session.message=err.message;      return res.redirect('/');    }    res.render('index',{      posts:posts    });  });});//發表微博router.post('/post',function(req, res, next){  var currentUser=req.session.user;  var post=new Post({    user:currentUser.name,    post:req.body.article,    updated:getTime(new Date())  });  post.save(function(err){    if(err){      req.session.message=err.message;      return res.redirect('/reg');    }    req.session.success="發表成功";    res.redirect('/users/'+currentUser.name);  });});function getTime(date){  return date.getFullYear()+  "-"+date.getMonth()+1+"-"+  date.getDate()+" "+  date.getHours()+":"+  date.getMinutes();}router.get('/reg', isLogin);//用戶進入注冊頁面router.get('/reg',function(req,res){  res.render('reg',{title:"用戶注冊"});});router.post('/reg', isLogin);//用戶點擊注冊按鈕router.post('/reg',function(req,res){  if(req.body['password']!= req.body['passwordconf']){    req.session.error="兩次密碼不一致";    return res.redirect('/reg');  }  var md5=crypto.createHash('md5');  var password=md5.update(req.body.password).digest('base64');  var newUser=new User({    name:req.body['username'],    password:password  });  User.findOne({name:newUser.name},function(err,user){    if(user){      err="用戶名已經存在";    }    if(err){      req.session.error=err;      return res.redirect('/reg');    }    newUser.save(function(err){      if(err){        req.session.error=err.message;        return res.redirect('/reg');      }      req.session.user=newUser;      req.session.success="注冊成功";      res.redirect('/');    });  });});router.get('/login',isLogin);router.get('/login',function(req,res){  res.render('login',{title:"用戶登陸"});});router.post('/login',isLogin);router.post('/login',function(req,res){  var md5=crypto.createHash('md5');  var password=md5.update(req.body.password).digest('base64');  User.findOne({name:req.body.username},function(err,user){    if(!user){      req.session.error="用戶不存在";      return res.redirect('/login');    }    if(user.password!=password){      req.session.error="密碼錯誤";      return res.redirect('/login');    }      req.session.user=user;      req.session.success="登錄成功";      res.redirect('/');  });});router.get('/logout',function(req,res){  req.session.user=null;  res.redirect('/');});function isLogin(req,res,next){  if(req.session.user){    req.session.message="用戶已登錄";    return res.redirect('/');  }  next();}module.exports = router;

上述代碼1-6行都是對外部模塊的引入,8-19行是對首頁路由/的處理代碼。117行將該模塊定義為router供外部調用。我們主要看54-83行,這些代碼就是用戶注冊的代碼,54行監聽來自用戶對于/reg路由的post請求,首先判斷兩次密碼是否一致,如果不一致在session中存儲一個錯誤信息然后跳轉到到當前頁面顯示錯誤信息,該錯誤信息供模板引擎顯示給用戶。如果兩次密碼一致首先對密碼進行md5加密,使用的是nodejs提供的核心模塊crypto,并生成一個對象模型User,該對象模型是mongoose中提供的一個model的實例,mongoose在它上面定義了一些操作數據庫的方法。然后調用這個實例的findOne方法檢測該用戶是否已經存在,如果存在就保存錯誤信息到session并跳轉到當前頁顯示錯誤。如果不存在這樣一個用戶就使用save方法進行用戶信息保存,注冊成功后將用戶信息保存在session中,并保存一個success的提示信息,然后跳轉到首頁。這里需要注意一個坑,以前做php或者.net的時候,我們通常都是先查詢數據庫等數據庫返回結果提示用戶是否存在之后再進行用戶的save然后在跳轉,這是一種同步方式,跳轉操作需要等待findOne操作返回結果之后才能進行。而nodejs中采用異步IO,最后的跳轉操作需要放在findOne操作的回調函數中進行,跳轉操作不必等待findone操作結束后執行,兩者是異步的。如果將最后的redirect操作放在findOne操作外部而不是回調函數中,你會在控制臺上得到一個Can't set headers after they are sent的錯誤,這是因為在fineOne以及save操作之前已經進行行了跳轉,response響應已經結束,不能夠重復響應請求。

到目前為止,用戶注冊模塊基本上已經差不多完成了,最后需要說一下如何在頁面上顯示提示信息或者錯誤信息,之前我們將提示信息或者錯誤信息都保存在了session中,jade要顯示錯誤信息,它是不能夠直接訪問session的,在express2.X即原書中是利用req.flash API+動態視圖助手來實現的,就是發生錯誤的時候先將其利用req.flash方法存儲下來,然后利用動態視圖助手結合模板去渲染給用戶。express4.X廢棄了這種方式,我們可以利用req.flash 的原理來自己模擬一個這種機制,同時利用res.locals變量被保存起來,模板在渲染的時候是能夠訪問到服務端這個變量的。關于res.locals的更多介紹請查看文檔。

為了模擬這種req.flash機制,我們在項目入口文件app.js(項目根目錄下)添加一段代碼如下:

app.use(function(req,res,next){//  res.locals.user=req.session.user;  var err=req.session.error;  var success=req.session.success;  var user=req.session.user;  var mess=req.session.message;  delete req.session.success;  delete req.session.error;  delete req.session.message;  if(err){    res.locals.message="*"+err;  }  if(mess){    res.locals.message="*"+mess;  }  if(success){    res.locals.success=success;  }  if(user){    res.locals.user=user.name;  }  next();});

這段代碼的意思是用戶請求和響應的時候,捕獲session中存儲的錯誤信息和用戶提示,將其存儲在response.locals變量中,這樣模板就能夠獲取。對于錯誤信息和提示,由于只使用一次,存儲后立即使用delete刪除,對于用戶信息,需要持久保存下來,則不刪除。

這樣,就能夠顯示用戶提示或者錯誤信息。

下面演示一下完整的用戶注冊流程以及錯誤信息提示。

當用戶名存在或密碼不一致時,

當注冊成功后跳轉到首頁并顯示用戶注冊成功

同時對于注冊成功和登陸成功擁有不同提示,如果該用戶已經是登錄狀態則顯示退出和發表文章按鈕,如果沒有登錄,則顯示的是登陸和立即注冊按鈕。

上述就是錯新技術頻道小編為大家帶來的詳解node.js進行web開發的操作方法,我們可以利用小編為大家的介紹實際操作一番,這樣還能積攢一些經驗。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 济源市| 增城市| 海口市| 确山县| 南开区| 宁明县| 辽宁省| 平乐县| 会泽县| 务川| 胶南市| 中江县| 韩城市| 宝应县| 铜陵市| 宿松县| 海南省| 偏关县| 句容市| 稻城县| 武宣县| 前郭尔| 简阳市| 蕲春县| 忻州市| 师宗县| 宝坻区| 航空| 阿鲁科尔沁旗| 三河市| 望江县| 宝山区| 来凤县| 仁化县| 三门县| 棋牌| 额济纳旗| 新乐市| 同江市| 舒城县| 星子县|