日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

nodejs 框架 中文express 4.xxx中文API手册

發布時間:2024/6/21 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 nodejs 框架 中文express 4.xxx中文API手册 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?介于最近express 中文文檔比較難找的現狀,特地找了一個,供大家學習思考

Express 4.x API

express?翻譯?api文檔?中文


--

express()

express()用來創建一個Express的程序。express()方法是express模塊導出的頂層方法。

  • var express = require('express');
  • var app = express();
  • Methods

    express.static(root, [options])

    express.static是Express中唯一的內建中間件。它以server-static模塊為基礎開發,負責托管 Express 應用內的靜態資源。?
    參數root為靜態資源的所在的根目錄。?
    參數options是可選的,支持以下的屬性:

    屬性描述類型默認值
    dotfiles是否響應點文件。供選擇的值有"allow","deny"和"ignore"String"ignore"
    etag使能或者關閉etagBooleantrue
    extensions設置文件延期回退Booleantrue
    index發送目錄索引文件。設置false將不發送。Mixed"index.html"
    lastModified設置文件在系統中的最后修改時間到Last-Modified頭部。可能的取值有false和true。Booleantrue
    maxAge在Cache-Control頭部中設置max-age屬性,精度為毫秒(ms)或則一段ms format的字符串Number0
    redirect當請求的pathname是一個目錄的時候,重定向到尾隨"/"Booleantrue
    setHeaders當響應靜態文件請求時設置headers的方法Funtion?

    如果你想獲得更多關于使用中間件的細節,你可以查閱Serving static files in Express。

    Application()

    app對象一般用來表示Express程序。通過調用Express模塊導出的頂層的express()方法來創建它:

  • var express = require('express');
  • var app = express();
  • app.get('/', function(req, res) {
  • res.send('hello world!');
  • });
  • app.listen(3000);
  • app對象具有以下的方法:

    • 路由HTTP請求;具體可以看app.METHOD和app.param這兩個例子。
    • 配置中間件;具體請看app.route。
    • 渲染HTML視圖;具體請看app.render。
    • 注冊模板引擎;具體請看app.engine。

    它還有一些屬性設置,這些屬性可以改變程序的行為。獲得更多的信息,可以查閱Application settings。

    Properties

    app.locals

    app.locals對象是一個javascript對象,它的屬性就是程序本地的變量。

  • app.locals.title
  • // => 'My App'
  • app.locals.email
  • // => 'me@myapp.com'
  • 一旦設定,app.locals的各屬性值將貫穿程序的整個生命周期,與其相反的是res.locals,它只在這次請求的生命周期中有效。

    在程序中,你可以在渲染模板時使用這些本地變量。它們是非常有用的,可以為模板提供一些有用的方法,以及app級別的數據。通過req.app.locals(具體查看req.app),Locals可以在中間件中使用。

  • app.locals.title = 'My App';
  • app.locals.strftime = require('strftime');
  • app.locals.email = 'me@myapp.com';
  • app.mountpath

    app.mountpath屬性是子程序掛載的路徑模式。

    一個子程序是一個express的實例,其可以被用來作為路由句柄來處理請求。

  • var express = require('express');
  • var app = express(); // the main app
  • var admin = express(); // the sub app
  • admin.get('/', function(req, res) {
  • console.log(admin.mountpath); // /admin
  • res.send('Admin Homepage');
  • });
  • app.use('/admin', admin); // mount the sub app
  • 它和req對象的baseUrl屬性比較相似,除了req.baseUrl是匹配的URL路徑,而不是匹配的模式。如果一個子程序被掛載在多條路徑模式,app.mountpath就是一個關于掛載路徑模式項的列表,如下面例子所示。

  • var admin = express();
  • admin.get('/', function(req, res) {
  • console.log(admin.mountpath); // ['adm*n', '/manager']
  • res.send('Admin Homepage');
  • });
  • var secret = express();
  • secret.get('/', function(req, res) {
  • console.log(secret.mountpath); // /secr*t
  • res.send('Admin secret');
  • });
  • admin.use('/secr*t', secret); // load the 'secret' router on '/secr*t', on the 'admin' sub app
  • app.use(['/adm*n', '/manager'], admin); // load the 'admin' router on '/adm*n' and '/manager' , on the parent app
  • Events

    app.on('mount', callback(parent))

    當子程序被掛載到父程序時,mount事件被發射。父程序對象作為參數,傳遞給回調方法。

  • var admin = express();
  • admin.on('mount', function(parent) {
  • console.log('Admin Mounted');
  • console.log(parent); // refers to the parent app
  • });
  • admin.get('/', function(req, res) {
  • res.send('Admin Homepage');
  • });
  • app.use('/admin', admin);
  • Methods

    app.all(path, callback[, callback ...]

    app.all方法和標準的app.METHOD()方法相似,除了它匹配所有的HTTP動詞。?
    對于給一個特殊前綴映射一個全局的邏輯處理,或者無條件匹配,它是很有效的。例如,如果你把下面內容放在所有其他的路由定義的前面,它要求所有從這個點開始的路由需要認證和自動加載一個用戶。記住這些回調并不是一定是終點:loadUser可以在完成了一個任務后,調用next()方法來繼續匹配隨后的路由。

  • app.all('*', requireAuthentication, loadUser);
  • 或者這種相等的形式:

  • app.all('*', requireAuthentication);
  • app.all('*', loadUser);
  • 另一個例子是全局的白名單方法。這個例子和前面的很像,然而它只是限制以/api開頭的路徑。

  • app.all('/api/*', requireAuthentication);
  • app.delete(path, callback[, callback ...])

    路由HTTP DELETE請求到有特殊回調方法的特殊的路徑。獲取更多的信息,可以查閱routing guide。?
    你可以提供多個回調函數,它們的行為和中間件一樣,除了這些回調可以通過調用next('router')來繞過剩余的路由回調。你可以使用這個機制來為一個路由設置一些前提條件,如果不能滿足當前路由的處理條件,那么你可以傳遞控制到隨后的路由。

  • app.delete('/', function(req, res) {
  • res.send('DELETE request to homepage');
  • });
  • app.disable(name)

    設置類型為布爾的設置名為name的值為false,此處的name是app settings table中各屬性的一個。調用app.set('foo', false)和調用app.disable('foo')是等價的。?
    比如:

  • app.disable('trust proxy');
  • app.get('trust proxy');
  • // => false
  • app.disabled(name)

    返回true如果布爾類型的設置值name被禁用為false,此處的name是app settings table中各屬性的一個。

  • app.disabled('trust proxy');
  • // => true
  • app.enable('trust proxy');
  • app.disabled('trust proxy');
  • // => false
  • app.enable(name)

    設置布爾類型的設置值name為true,此處的name是app settings table中各屬性的一個。調用app.set('foo', true)和調用app.enable('foo')是等價的。

  • app.enable('trust proxy');
  • app.get('trust proxy');
  • // => true
  • app.enabled(name)

    返回true如果布爾類型的設置值name被啟動為true,此處的name是app settings table中各屬性的一個。

  • app.enabled('trust proxy');
  • // => false
  • app.enable('trust proxy');
  • app.enabled('trust proxy');
  • // => true
  • app.engine(ext, callback)

    注冊給定引擎的回調,用來渲染處理ext文件。?
    默認情況下,Express需要使用require()來加載基于文件擴展的引擎。例如,如果你嘗試渲染一個foo.jade文件,Express在內部調用下面的內容,同時緩存require()結果供隨后的調用,來加速性能。

  • app.engine('jade', require('jade').__express);
  • 使用下面的方法對于那些沒有提供開箱即用的.__express方法的模板,或者你希望使用不同的模板引擎擴展。?
    比如,使用EJS模板引擎來渲染.html文件:

  • app.engine('html', require('ejs').renderFile);
  • 在這個例子中,EJS提供了一個.renderFile方法,這個方法滿足了Express規定的簽名規則:(path, options, callback),然而記住在內部它只是ejs.__express的一個別名,所以你可以在不做任何事的情況下直接使用.ejs擴展。?
    一些模板引擎沒有遵循這種規范,consolidate.js庫映射模板引擎以下面的使用方式,所以他們可以無縫的和Express工作。

  • var engines = require('consolidate');
  • app.engine('haml', engines.haml);
  • app.engine('html', engines.hogan);
  • app.get(name)

    獲得設置名為name的app設置的值,此處的name是app settings table中各屬性的一個。?
    如下:

  • app.get('title');
  • // => undefined
  • app.set('title', 'My Site');
  • app.get('title');
  • // => 'My Site'
  • app.get(path, callback [, callback ...])

    路由HTTP GET請求到有特殊回調的特殊路徑。獲取更多的信息,可以查閱routing guide。?
    你可以提供多個回調函數,它們的行為和中間件一樣,除了這些回調可以通過調用next('router')來繞過剩余的路由回調。你可以使用這個機制來為一個路由設置一些前提條件,如果請求沒能滿足當前路由的處理條件,那么傳遞控制到隨后的路由。

  • app.get('/', function(req, res) {
  • res.send('GET request to homepage');
  • });
  • app.listen(port, [hostname], [backlog], [callback])

    綁定程序監聽端口到指定的主機和端口號。這個方法和Node中的http.Server.listen()是一樣的。

  • var express = require('express');
  • var app = express();
  • app.listen(3000);
  • 通過調用express()返回得到的app實際上是一個JavaScript的Function,被設計用來作為一個回調傳遞給Node HTTP servers來處理請求。這樣,其就可以很簡便的基于同一份代碼提供http和https版本,所以app沒有從這些繼承(它只是一個簡單的回調)。

  • var express = require('express');
  • var https = require('https');
  • var http = require('http');
  • http.createServer(app).listen(80);
  • https.createServer(options, app).listen(443);
  • app.listen()方法是下面所示的一個便利的方法(只針對HTTP協議):

  • app.listen = function() {
  • var server = http.createServer(this);
  • return server.listen.apply(server, arguments);
  • };
  • app.METHOD(path, callback [, callback ...])

    路由一個HTTP請求,METHOD是這個請求的HTTP方法,比如GET,PUT,POST等等,注意是小寫的。所以,實際的方法是app.get(),app.post(),app.put()等等。下面有關于方法的完整的表。?
    獲取更多信息,請看routing guide。?
    Express支持下面的路由方法,對應與同名的HTTP方法:

    • checkout
    • connect
    • copy
    • delete
    • get
    • head
    • lock
    • merge
    • mkactivity
    • mkcol
    • move
    • m-search
    • notify
    • options
    • patch
    • post
    • propfind
    • proppatch
    • purege
    • put
    • report
    • search
    • subscribe
    • trace
    • unlock
    • unsubscribe

    如果使用上述方法時,導致了無效的javascript的變量名,可以使用中括號符號,比如,app['m-search']('/', function ...

    你可以提供多個回調函數,它們的行為和中間件一樣,除了這些回調可以通過調用next('router')來繞過剩余的路由回調。你可以使用這個機制來為一個路由設置一些前提條件,如果請求沒有滿足當前路由的處理條件,那么傳遞控制到隨后的路由。

    本API文檔把使用比較多的HTTP方法app.get(),app.post,app.put(),app.delete()作為一個個單獨的項進行說明。然而,其他上述列出的方法以完全相同的方式工作。

    app.all()是一個特殊的路由方法,它不屬于HTTP協議中的規定的方法。它為一個路徑加載中間件,其對所有的請求方法都有效。

  • app.all('/secret', function (req, res) {
  • console.log('Accessing the secret section...');
  • next(); // pass control to the next handler
  • });
  • app.param([name], callback)

    給路由參數添加回調觸發器,這里的name是參數名或者參數數組,function是回調方法。回調方法的參數按序是請求對象,響應對象,下個中間件,參數值和參數名。?
    如果name是數組,會按照各個參數在數組中被聲明的順序將回調觸發器注冊下來。還有,對于除了最后一個參數的其他參數,在他們的回調中調用next()來調用下個聲明參數的回調。對于最后一個參數,在回調中調用next()將調用位于當前處理路由中的下一個中間件,如果name只是一個string那就和它是一樣的(就是說只有一個參數,那么就是最后一個參數,和數組中最后一個參數是一樣的)。?
    例如,當:user出現在路由路徑中,你可以映射用戶加載的邏輯處理來自動提供req.user給這個路由,或者對輸入的參數進行驗證。

  • app.param('user', function(req, res, next, id) {
  • User.find(id, function(error, user) {
  • if (err) {
  • next(err);
  • }
  • else if (user){
  • req.user = user;
  • } else {
  • next(new Error('failed to load user'));
  • }
  • });
  • });
  • 對于Param的回調定義的路由來說,他們是局部的。它們不會被掛載的app或者路由繼承。所以,定義在app上的Param回調只有是在app上的路由具有這個路由參數時才起作用。?
    在定義param的路由上,param回調都是第一個被調用的,它們在一個請求-響應循環中都會被調用一次并且只有一次,即使多個路由都匹配,如下面的例子:

  • app.param('id', function(req, res, next, id) {
  • console.log('CALLED ONLY ONCE');
  • next();
  • });
  • app.get('/user/:id', function(req, res, next) {
  • console.log('although this matches');
  • next();
  • });
  • app.get('/user/:id', function(req, res) {
  • console.log('and this mathces too');
  • res.end();
  • });
  • 當GET /user/42,得到下面的結果:

  • CALLED ONLY ONCE
  • although this matches
  • and this matches too
  • app.param(['id', 'page'], function(req, res, next, value) {
  • console.log('CALLED ONLY ONCE with', value);
  • next();
  • });
  • app.get('/user/:id/:page', function(req. res, next) {
  • console.log('although this matches');
  • next();
  • });
  • app.get('/user/:id/:page', function (req, res, next) {
  • console.log('and this matches too');
  • res.end();
  • });
  • 當執行GET /user/42/3,結果如下:

  • CALLED ONLY ONCE with 42
  • CALLED ONLY ONCE with 3
  • although this matches
  • and this mathes too
  • 下面章節描述的app.param(callback)在v4.11.0之后被棄用。

    通過只傳遞一個回調參數給app.param(name, callback)方法,app.param(naem, callback)方法的行為將被完全改變。這個回調參數是關于app.param(name, callback)該具有怎樣的行為的一個自定義方法,這個方法必須接受兩個參數并且返回一個中間件。?
    這個回調的第一個參數就是需要捕獲的url的參數名,第二個參數可以是任一的JavaScript對象,其可能在實現返回一個中間件時被使用。?
    這個回調方法返回的中間件決定了當URL中包含這個參數時所采取的行為。?
    在下面的例子中,app.param(name, callback)參數簽名被修改成了app.param(name, accessId)。替換接受一個參數名和回調,app.param()現在接受一個參數名和一個數字。

  • var express = require('express');
  • var app = express();
  • app.param(function(param, option){
  • return function(req, res, next, val) {
  • if (val == option) {
  • next();
  • }
  • else {
  • res.sendStatus(403);
  • }
  • }
  • });
  • app.param('id', 1337);
  • app.get('/user/:id', function(req, res) {
  • res.send('Ok');
  • });
  • app.listen(3000, function() {
  • console.log('Ready');
  • });
  • 在這個例子中,app.param(name, callback)參數簽名保持和原來一樣,但是替換成了一個中間件,定義了一個自定義的數據類型檢測方法來檢測user id的類型正確性。

  • app.param(function(param, validator) {
  • return function(req, res, next, val) {
  • if (validator(val)) {
  • next();
  • }
  • else {
  • res.sendStatus(403);
  • }
  • }
  • });
  • app.param('id', function(candidate) {
  • return !isNaN(parseFloat(candidate)) && isFinite(candidate);
  • });
  • 在使用正則表達式來,不要使用.。例如,你不能使用/user-.+/來捕獲user-gami,用使用[\\s\\S]或者[\\w\\>W]來代替(正如/user-[\\s\\S]+/)。

  • //captures '1-a_6' but not '543-azser-sder'
  • router.get('/[0-9]+-[[\\w]]*', function);
  • //captures '1-a_6' and '543-az(ser"-sder' but not '5-a s'
  • router.get('/[0-9]+-[[\\S]]*', function);
  • //captures all (equivalent to '.*')
  • router.get('[[\\s\\S]]*', function);
  • app.path()

    通過這個方法可以得到app典型的路徑,其是一個string。

  • var app = express()
  • , blog = express()
  • , blogAdmin = express();
  • app.use('/blog', blog);
  • app.use('/admin', blogAdmin);
  • console.log(app.path()); // ''
  • console.log(blog.path()); // '/blog'
  • console.log(blogAdmin.path()); // '/blog/admin'
  • 如果app掛載很復雜下,那么這個方法的行為也會很復雜:一種更好用的方式是使用req.baseUrl來獲得這個app的典型路徑。

    app.post(path, callback, [callback ...])

    路由HTTP POST請求到有特殊回調的特殊路徑。獲取更多的信息,可以查閱routing guide。?
    你可以提供多個回調函數,它們的行為和中間件一樣,除了這些回調可以通過調用next('router')來繞過剩余的路由回調。你可以使用這個機制來為一個路由設置一些前提條件,如果請求沒能滿足當前路由的處理條件,那么傳遞控制到隨后的路由。

  • app.post('/', function(req, res) {
  • res.send('POST request to homepage')
  • });
  • app.put(path, callback, [callback ...])

    路由HTTP PUT請求到有特殊回調的特殊路徑。獲取更多的信息,可以查閱routing guide。?
    你可以提供多個回調函數,它們的行為和中間件一樣,除了這些回調可以通過調用next('router')來繞過剩余的路由回調。你可以使用這個機制來為一個路由設置一些前提條件,如果請求沒能滿足當前路由的處理條件,那么傳遞控制到隨后的路由。

  • app.put('/', function(req, res) {
  • res.send('PUT request to homepage');
  • });
  • app.render(view, [locals], callback)

    通過callback回調返回一個view渲染之后得到的HTML文本。它可以接受一個可選的參數,可選參數包含了這個view需要用到的本地數據。這個方法類似于res.render(),除了它不能把渲染得到的HTML文本發送給客戶端。

    將app.render()當作是可以生成渲染視圖字符串的工具方法。在res.render()內部,就是使用的app.render()來渲染視圖。

    如果使能了視圖緩存,那么本地變量緩存就會保留。如果你想在開發的過程中緩存視圖,設置它為true。在生產環境中,視圖緩存默認是打開的。

  • app.render('email', function(err, html) {
  • // ...
  • });
  • app.render('email', {name:'Tobi'}, function(err, html) {
  • // ...
  • });
  • app.route(path)

    返回一個單例模式的路由的實例,之后你可以在其上施加各種HTTP動作的中間件。使用app.route()來避免重復路由名字(因此錯字錯誤)--說的意思應該是使用app.router()這個單例方法來避免同一個路徑多個路由實例。

  • var app = express();
  • app.route('/events')
  • .all(function(req, res, next) {
  • // runs for all HTTP verbs first
  • // think of it as route specific middleware!
  • })
  • .get(function(req, res, next) {
  • res.json(...);
  • })
  • .post(function(req, res, next) {
  • // maybe add a new event...
  • })
  • app.set(name, value)

    給name設置項賦value值,name是app settings table中屬性的一項。?
    對于一個類型是布爾型的屬性調用app.set('foo', ture)等價于調用app.enable('foo')。同樣的,調用app.set('foo', false)等價于調用app.disable('foo')。?
    可以使用app.get()來取得設置的值:

  • app.set('title', 'My Site');
  • app.get('title'); // 'My Site'
  • Application Settings?
    如果name是程序設置之一,它將影響到程序的行為。下邊列出了程序中的設置。

    PropertyTypeValueDefault
    case sensitive routingBoolean啟用區分大小寫。不啟用。對/Foo和/foo處理是一樣。
    envString環境模型。process.env.NODE_ENV(NODE_ENV環境變量)或者"development"
    etagVaried設置ETag響應頭。可取的值,可以查閱etag options table。更多關于HTTP ETag header。weak
    jsonp callback nameString指定默認JSONP回調的名稱。?callback=
    json replacerStringJSON替代品回調null
    json spacesNumber當設置了這個值后,發送縮進空格美化過的JSON字符串。Disabled
    query parserVaried設置值為false來禁用query parser,或者設置simple,extended,也可以自己實現query string解析函數。simple基于Node原生的query解析,querystring。"extend"
    strict routingBoolean啟用嚴格的路由。不啟用。對/foo和/foo/的路由處理是一樣。
    subdomain offsetNumber用來刪除訪問子域的主機點分部分的個數2
    trust proxyVaried指示app在一個反向代理的后面,使用x-Forwarded-*來確定連接和客戶端的IP地址。注意:X-Forwarded-*頭部很容易被欺騙,所有檢測客戶端的IP地址是靠不住的。trust proxy默認不啟用。當啟用時,Express嘗試通過前端代理或者一系列代理來獲取已連接的客戶端IP地址。req.ips屬性包含了已連接客戶端IP地址的一個數組。為了啟動它,需要設置在下面trust proxy options table中定義的值。trust proxy的設置實現使用了proxy-addr包。如果想獲得更多的信息,可以查閱它的文檔Disable
    viewsString or Arrayview所在的目錄或者目錄數組。如果是一個數組,將按在數組中的順序來查找view。process.cwd() + '/views'
    view cacheBoolean啟用視圖模板編譯緩存。在生成環境默認開啟。
    view engineString省略時,默認的引擎被擴展使用。?
    x-powered-byBoolean啟用X-Powered-By:ExpressHTTP頭部true

    Options for?trust proxy?settings?
    查閱Express behind proxies來獲取更多信息。

    TypeValue
    Boolean

    如果為true,客戶端的IP地址作為X-Forwarded-*頭部的最左邊的條目。如果為false,可以理解為app直接與英特網直連,客戶端的IP地址衍生自req.connection.remoteAddress。false是默認設置。

    IP addresses

    一個IP地址,子網,或者一組IP地址,和委托子網。下面列出的是一個預先配置的子網名列表。

    • loopback -?127.0.0.1/8,?::1/128
    • linklocal -?169.254.0.0/16,?fe80::/10
    • uniquelocal -?10.0.0.0/8,?172.16.0.0/12,?192.168.0.0/16,?fc00::/7

    使用下面方法中的任何一種來設置IP地址:

    app.set('trust proxy', 'loopback') // specify a single subnet app.set('trust proxy', 'loopback, 123.123.123.123') // specify a subnet and an address app.set('trust proxy', 'loopback, linklocal, uniquelocal') // specify multiple subnets as CSV app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']) // specify multiple subnets as an array

    當指定IP地址之后, 這個IP地址或子網會被設置了這個IP地址或子網的`app`排除在外, 最靠近程序服務的沒有委托的地址將被看做客戶端IP地址。

    Number

    信任從反向代理到app中間小于等于n跳的連接為客戶端。

    Function

    客戶自定義委托代理信任機制。如果你使用這個,請確保你自己知道你在干什么。

    app.set('trust proxy', function (ip) { if (ip === '127.0.0.1' || ip === '123.123.123.123') return true; // trusted IPs else return false; })

    Options for?etag?settings?
    ETag功能的實現使用了etag包。如果你需要獲得更多的信息,你可以查閱它的文檔。

    TypeValue
    Boolean

    設置為true,啟用weak ETag。這個是默認設置。設置false,禁用所有的ETag。

    String如果是strong,使能strong ETag。如果是weak,啟用weak?ETag。
    Function

    客戶自定義`ETag`方法的實現. 如果你使用這個,請確保你自己知道你在干什么。

    app.set('etag', function (body, encoding) { return generateHash(body, encoding); // consider the function is defined })

    app.use([path,], function [, function...])

    掛載中間件方法到路徑上。如果路徑未指定,那么默認為"/"。

    一個路由將匹配任何路徑如果這個路徑以這個路由設置路徑后緊跟著"/"。比如:app.use('/appale', ...)將匹配"/apple","/apple/images","/apple/images/news"等。

    中間件中的req.originalUrl是req.baseUrl和req.path的組合,如下面的例子所示。

  • app.use('/admin', function(req, res, next) {
  • // GET 'http://www.example.com/admin/new'
  • console.log(req.originalUrl); // '/admin/new'
  • console.log(req.baseUrl); // '/admin'
  • console.log(req.path);// '/new'
  • });
  • 在一個路徑上掛載一個中間件之后,每當請求的路徑的前綴部分匹配了這個路由路徑,那么這個中間件就會被執行。?
    由于默認的路徑為/,中間件掛載沒有指定路徑,那么對于每個請求,這個中間件都會被執行。

  • // this middleware will be executed for every request to the app.
  • app.use(function(req, res, next) {
  • console.log('Time: %d', Date.now());
  • next();
  • });
  • 中間件方法是順序處理的,所以中間件包含的順序是很重要的。

  • // this middleware will not allow the request to go beyond it
  • app.use(function(req, res, next) {
  • res.send('Hello World');
  • });
  • // this middleware will never reach this route
  • app.use('/', function(req, res) {
  • res.send('Welcome');
  • });
  • 路徑可以是代表路徑的一串字符,一個路徑模式,一個匹配路徑的正則表達式,或者他們的一組集合。

    下面是路徑的簡單的例子。

    TypeExample
    Path // will match paths starting with /abcd app.use('/abcd', function (req, res, next) { next(); })
    Path Pattern // will match paths starting with /abcd and /abd app.use('/abc?d', function (req, res, next) { next(); }) // will match paths starting with /abcd, /abbcd, /abbbbbcd and so on app.use('/ab+cd', function (req, res, next) { next(); }) // will match paths starting with /abcd, /abxcd, /abFOOcd, /abbArcd and so on app.use('/ab\*cd', function (req, res, next) { next(); }) // will match paths starting with /ad and /abcd app.use('/a(bc)?d', function (req, res, next) { next(); })
    Regular Expression // will match paths starting with /abc and /xyz app.use(/\/abc|\/xyz/, function (req, res, next) { next(); })
    Array // will match paths starting with /abcd, /xyza, /lmn, and /pqr app.use(['/abcd', '/xyza', /\/lmn|\/pqr/], function (req, res, next) { next(); })

    方法可以是一個中間件方法,一系列中間件方法,一組中間件方法或者他們的集合。由于router和app實現了中間件接口,你可以像使用其他任一中間件方法那樣使用它們。

    UsageExample
    單個中間件你可以局部定義和掛載一個中間件。 app.use(function (req, res, next) { next(); }) 一個router是有效的中間件。 var router = express.Router(); router.get('/', function (req, res, next) { next(); }) app.use(router); 一個Express程序是一個有效的中間件。 var subApp = express(); subApp.get('/', function (req, res, next) { next(); }) app.use(subApp);
    一系列中間件對于一個相同的掛載路徑,你可以掛載超過一個的中間件。 var r1 = express.Router(); r1.get('/', function (req, res, next) { next(); }) var r2 = express.Router(); r2.get('/', function (req, res, next) { next(); }) app.use(r1, r2);
    一組中間件在邏輯上使用一個數組來組織一組中間件。如果你傳遞一組中間件作為第一個或者唯一的參數,接著你需要指定掛載的路徑。 var r1 = express.Router(); r1.get('/', function (req, res, next) { next(); }) var r2 = express.Router(); r2.get('/', function (req, res, next) { next(); }) app.use('/', [r1, r2]);
    組合你可以組合下面的所有方法來掛載中間件。 function mw1(req, res, next) { next(); } function mw2(req, res, next) { next(); } var r1 = express.Router(); r1.get('/', function (req, res, next) { next(); }); var r2 = express.Router(); r2.get('/', function (req, res, next) { next(); }); var subApp = express(); subApp.get('/', function (req, res, next) { next(); }); app.use(mw1, [mw2, r1, r2], subApp);

    下面是一些例子,在Express程序中使用express.static中間件。?
    為程序托管位于程序目錄下的public目錄下的靜態資源:

  • // GET /style.css etc
  • app.use(express.static(__dirname + '/public'));
  • 在/static路徑下掛載中間件來提供靜態資源托管服務,只當請求是以/static為前綴的時候。

  • // GET /static/style.css etc.
  • app.use('/static', express.static(express.__dirname + '/public'));
  • 通過在設置靜態資源中間件之后加載日志中間件來關閉靜態資源請求的日志。

  • app.use(express.static(__dirname + '/public'));
  • app.use(logger());
  • 托管靜態資源從不同的路徑,但./public路徑比其他更容易被匹配:

  • app.use(express.static(__dirname + '/public'));
  • app.use(express.static(__dirname + '/files'));
  • app.use(express.static(__dirname + '/uploads'));
  • Request

    req對象代表了一個HTTP請求,其具有一些屬性來保存請求中的一些數據,比如query string,parameters,body,HTTP headers等等。在本文檔中,按照慣例,這個對象總是簡稱為req(http響應簡稱為res),但是它們實際的名字由這個回調方法在那里使用時的參數決定。?
    如下例子:

  • app.get('/user/:id', function(req, res) {
  • res.send('user' + req.params.id);
  • });
  • 其實你也可以這樣寫:

  • app.get('/user/:id', function(request, response) {
  • response.send('user' + request.params.id);
  • });
  • Properties

    在Express 4中,req.files默認在req對象中不再是可用的。為了通過req.files對象來獲得上傳的文件,你可以使用一個multipart-handling(多種處理的工具集)中間件,比如busboy,multer,formidable,multipraty,connect-multiparty或者pez。

    req.app

    這個屬性持有express程序實例的一個引用,其可以作為中間件使用。?
    如果你按照這個模式,你創建一個模塊導出一個中間件,這個中間件只在你的主文件中require()它,那么這個中間件可以通過req.app來獲取express的實例。?
    例如:

  • // index.js
  • app.get("/viewdirectory", require('./mymiddleware.js'));
  • // mymiddleware.js
  • module.exports = function(req, res) {
  • res.send('The views directory is ' + req.app.get('views'));
  • };
  • req.baseUrl

    一個路由實例掛載的Url路徑。

  • var greet = express.Router();
  • greet.get('/jp', function(req, res) {
  • console.log(req.baseUrl); // greet
  • res.send('Konichiwa!');
  • });
  • app.use('/greet', greet);
  • 即使你使用的路徑模式或者一系列路徑模式來加載路由,baseUrl屬性返回匹配的字符串,而不是路由模式。下面的例子,greet路由被加載在兩個路徑模式上。

  • app.use(['/gre+t', 'hel{2}o'], greet); // load the on router on '/gre+t' and '/hel{2}o'
  • 當一個請求路徑是/greet/jp,baseUrl是/greet,當一個請求路徑是/hello/jp,req.baseUrl是/hello。?
    req.baseUrl和app對象的mountpath屬性相似,除了app.mountpath返回的是路徑匹配模式。

    req.body

    在請求的body中保存的是提交的一對對鍵值數據。默認情況下,它是undefined,當你使用比如body-parser和multer這類解析body數據的中間件時,它是填充的。?
    下面的例子,給你展示了怎么使用body-parser中間件來填充req.body。

  • var app = require('express');
  • var bodyParser = require('body-parser');
  • var multer = require('multer');// v1.0.5
  • var upload = multer(); // for parsing multipart/form-data
  • app.use(bodyParser.json()); // for parsing application/json
  • app.use(bodyParser.urlencoded({extended:true})); // for parsing application/x-www-form-urlencoded
  • app.post('/profile', upload.array(), function(req, res, next) {
  • console.log(req.body);
  • res.json(req.body);
  • });
  • req.cookies

    當使用cookie-parser中間件的時候,這個屬性是一個對象,其包含了請求發送過來的cookies。如果請求沒有帶cookies,那么其值為{}。

  • // Cookie: name=tj
  • req.cookies.name
  • // => "tj"
  • 獲取更多信息,問題,或者關注,可以查閱cookie-parser。

    req.fresh

    指示這個請求是否是新鮮的。其和req.stale是相反的。?
    當cache-control請求頭沒有no-cache指示和下面中的任一一個條件為true,那么其就為true:

    • if-modified-since請求頭被指定,和last-modified請求頭等于或者早于modified響應頭。
    • if-none-match請求頭是*。
    • if-none-match請求頭在被解析進它的指令之后,不匹配etag響應頭(完全不知道什么鬼)。
  • req.fresh
  • // => true
  • req.hostname

    包含了源自HostHTTP頭部的hostname。?
    當trust proxy設置項被設置為啟用值,X-Forwarded-Host頭部被使用來代替Host。這個頭部可以被客戶端或者代理設置。

  • // Host: "example.com"
  • req.hostname
  • // => "example.com"
  • req.ips

    當trust proxy設置項被設置為啟用值,這個屬性包含了一組在X-Forwarded-For請求頭中指定的IP地址。不然,其就包含一個空的數組。這個頭部可以被客戶端或者代理設置。?
    例如,如果X-Forwarded-For是client,proxy1,proxy2,req.ips就是["clinet", "proxy1", "proxy2"],這里proxy2就是最遠的下游。

    req.originalUrl

    req.url不是一個原生的Express屬性,它繼承自Node's http module。

    這個屬性很像req.url;然而,其保留了原版的請求鏈接,允許你自由地重定向req.url到內部路由。比如,app.use()的mounting特點可以重定向req.url跳轉到掛載點。

  • // GET /search?q=something
  • req.originalUrl
  • // => "/search?q=something"
  • req.params

    一個對象,其包含了一系列的屬性,這些屬性和在路由中命名的參數名是一一對應的。例如,如果你有/user/:name路由,name屬性可作為req.params.name。這個對象默認值為{}。

  • // GET /user/tj
  • req.params.name
  • // => "tj"
  • 當你使用正則表達式來定義路由規則,捕獲組的組合一般使用req.params[n],這里的n是第幾個捕獲租。這個規則被施加在無名通配符匹配,比如/file/*的路由:

  • // GET /file/javascripts/jquery.js
  • req.params[0]
  • // => "javascripts/jquery.js"
  • req.path

    包含請求URL的部分路徑。

  • // example.com/users?sort=desc
  • req.path
  • // => "/users"
  • 當在一個中間件中被調用,掛載點不包含在req.path中。你可以查閱app.use()獲得跟多的信息。

    req.protocol

    請求的協議,一般為http,當啟用TLS加密,則為https。?
    當trust proxy設置一個啟用的參數,如果存在X-Forwarded-Proto頭部的話,其將被信賴和使用。這個頭部可以被客戶端或者代理設置。

  • req.ptotocol
  • // => "http"
  • req.query

    一個對象,為每一個路由中的query string參數都分配一個屬性。如果沒有query string,它就是一個空對象,{}。

  • // GET /search?q=tobi+ferret
  • req.query.q
  • // => "tobi ferret"
  • // GET /shoes?order=desc&shoe[color]=blue&shoe[type]=converse
  • req.query.order
  • // => "desc"
  • req.query.shoe.color
  • // => "blue"
  • req.query.shoe.type
  • // => "converse"
  • req.route

    當前匹配的路由,其為一串字符。比如:

  • app.get('/user/:id?', function userIdHandler(req, res) {
  • console.log(req.route);
  • res.send('GET')
  • })
  • 前面片段的輸出為:

  • { path:"/user/:id?"
  • stack:
  • [
  • { handle:[Function:userIdHandler],
  • name:"userIdHandler",
  • params:undefined,
  • path:undefined,
  • keys:[],
  • regexp:/^\/?$/i,
  • method:'get'
  • }
  • ]
  • methods:{get:true}
  • }
  • req.secure

    一個布爾值,如果建立的是TLS的連接,那么就為true。等價與:

  • 'https' == req.protocol;
  • req.signedCookies

    當使用cookie-parser中間件的時候,這個屬性包含的是請求發過來的簽名cookies,不簽名的并且為使用做好了準備(這句真不知道怎么翻譯了...)。簽名cookies駐留在不同的對象中來體現開發者的意圖;不然,一個惡意攻擊可以被施加在req.cookie值上(它是很容易被欺騙的)。記住,簽名一個cookie不是把它藏起來或者加密;而是簡單的防止篡改(因為簽名使用的加密是私人的)。如果沒有發送簽名的cookie,那么這個屬性默認為{}。

  • // Cookie: user=tobi.CP7AWaXDfAKIRfH49dQzKJx7sKzzSoPq7/AcBBRVwlI3
  • req.signedCookies.user
  • // => "tobi"
  • 為了獲取更多的信息,問題或者關注,可以參閱cookie-parser。

    req.stale

    指示這個請求是否是stale(陳舊的),它與req.fresh是相反的。更多信息,可以查看req.fresh。

  • req.stale
  • // => true
  • req.subdomains

    請求中域名的子域名數組。

  • // Host: "tobi.ferrets.example.com"
  • req.subdomains
  • // => ["ferrets", "tobi"]
  • req.xhr

    一個布爾值,如果X-Requested-With的值為XMLHttpRequest,那么其為true,其指示這個請求是被一個客服端庫發送,比如jQuery。

  • req.xhr
  • // => true
  • Methods

    req.accepts(types)

    檢查這個指定的內容類型是否被接受,基于請求的Accept?HTTP頭部。這個方法返回最佳匹配,如果沒有一個匹配,那么其返回undefined(在這個case下,服務器端應該返回406和"Not Acceptable")。?
    type值可以是一個單的MIME type字符串(比如application/json),一個擴展名比如json,一個逗號分隔的列表,或者一個數組。對于一個列表或者數組,這個方法返回最佳項(如果有的話)。

  • // Accept: text/html
  • req.accepts('html');
  • // => "html"
  • // Accept: text/*, application/json
  • req.accepts('html');
  • // => "html"
  • req.accepts('text/html');
  • // => "text/html"
  • req.accepts(['json', 'text']);
  • // => "json"
  • req.accepts('application/json');
  • // => "application/json"
  • // Accept: text/*, application/json
  • req.accepts('image/png');
  • req.accepts('png');
  • // => undefined
  • // Accept: text/*;q=.5, application/json
  • req.accepts(['html', 'json']);
  • // => "json"
  • 獲取更多信息,或者如果你有問題或關注,可以參閱accepts。

    req.acceptsCharsets(charset[, ...])

    返回指定的字符集集合中第一個的配置的字符集,基于請求的Accept-CharsetHTTP頭。如果指定的字符集沒有匹配的,那么就返回false。?
    獲取更多信息,或者如果你有問題或關注,可以參閱accepts。

    req.acceptsEncodings(encoding[, ...])

    返回指定的編碼集合中第一個的配置的編碼,基于請求的Accept-EncodingHTTP頭。如果指定的編碼集沒有匹配的,那么就返回false。?
    獲取更多信息,或者如果你有問題或關注,可以參閱accepts。

    req.acceptsLanguages(lang [, ...])

    返回指定的語言集合中第一個的配置的語言,基于請求的Accept-LanguageHTTP頭。如果指定的語言集沒有匹配的,那么就返回false。?
    獲取更多信息,或者如果你有問題或關注,可以參閱accepts。

    req.get(field)

    返回指定的請求HTTP頭部的域內容(不區分大小寫)。Referrer和Referer的域內容可互換。

  • req.get('Content-type');
  • // => "text/plain"
  • req.get('content-type');
  • // => "text/plain"
  • req.get('Something')
  • // => undefined
  • 其是req.header(field)的別名。

    req.is(type)

    如果進來的請求的Content-type頭部域匹配參數type給定的MIME type,那么其返回true。否則返回false。

  • // With Content-Type: text/html; charset=utf-8
  • req.is('html');
  • req.is('text/html');
  • req.is('text/*');
  • // => true
  • // When Content-Type is application/json
  • req.is('json');
  • req.is('application/json');
  • req.is('application/*');
  • // => true
  • req.is('html');
  • // => false
  • 獲取更多信息,或者如果你有問題或關注,可以參閱type-is。

    req.param(naem, [, defaultValue])

    過時的。可以在適合的情況下,使用req.params,req.body或者req.query。

    返回當前參數name的值。

  • // ?name=tobi
  • req.param('name')
  • // => "tobi"
  • // POST name=tobi
  • req.param('name')
  • // => "tobi"
  • // /user/tobi for /user/:name
  • req.param('name')
  • // => "tobi"
  • 按下面給出的順序查找:

    • req.params
    • req.body
    • req.query

    可選的,你可以指定一個defaultValue來設置一個默認值,如果這個參數在任何一個請求的對象中都不能找到。

    直接通過req.params,req.body,req.query取得應該更加的清晰-除非你確定每一個對象的輸入。?
    Body-parser中間件必須加載,如果你使用req.param()。詳細請看req.body。

    Response

    res對象代表了當一個HTTP請求到來時,Express程序返回的HTTP響應。在本文檔中,按照慣例,這個對象總是簡稱為res(http請求簡稱為req),但是它們實際的名字由這個回調方法在那里使用時的參數決定。?
    例如:

  • app.get('/user/:id', function(req, res) {
  • res.send('user' + req.params.id);
  • });
  • 這樣寫也是一樣的:

  • app.get('/user/:id', function(request, response) {
  • response.send('user' + request.params.id);
  • });
  • Properties

    res.app

    這個屬性持有express程序實例的一個引用,其可以在中間件中使用。?
    res.app和請求對象中的req.app屬性是相同的。

    res.headersSent

    布爾類型的屬性,指示這個響應是否已經發送HTTP頭部。

  • app.get('/', function(req, res) {
  • console.log(res.headersSent); // false
  • res.send('OK'); // send之后就發送了頭部
  • console.log(res.headersSent); // true
  • });
  • res.locals

    一個對象,其包含了響應的能夠反應出請求的本地參數和因此只提供給視圖渲染,在請求響應的周期內(如果有的話)--我要翻譯吐了。否則,其和app.locals是一樣的。(不知道翻譯的什么...)?
    這個參數在導出請求級別的信息是很有效的,這些信息比如請求路徑,已認證的用戶,用戶設置等等。

  • app.use(function(req, res, next) {
  • res.locals.user = req.user;
  • res.locals.authenticated = !req.user.anonymous;
  • next();
  • });
  • Methods

    res.append(field [, value])

    res.append()方法在Expresxs4.11.0以上版本才支持。

    在指定的field的HTTP頭部追加特殊的值value。如果這個頭部沒有被設置,那么將用value新建這個頭部。value可以是一個字符串或者數組。?
    注意:在res.append()之后調用app.set()函數將重置前面設置的值。

  • res.append('Lind', ['<http://localhost>', '<http://localhost:3000>']);
  • res.append('Set-Cookie', 'foo=bar;Path=/;HttpOnly');
  • res.append('Warning', '199 Miscellaneous warning');
  • res.attachment([filename])

    設置HTTP響應的Content-Disposition頭內容為"attachment"。如果提供了filename,那么將通過res.type()獲得擴展名來設置Content-Type,并且設置Content-Disposition內容為"filename="parameter。

  • res.attachment();
  • // Content-Disposition: attachment
  • res.attachment('path/to/logo.png');
  • // Content-Disposition: attachment; filename="logo.png"
  • // Content-Type: image/png
  • res.cookie(name, value [,options])

    設置name和value的cookie,value參數可以是一串字符或者是轉化為json字符串的對象。?
    options是一個對象,其可以有下列的屬性。

    屬性類型描述
    domainString設置cookie的域名。默認是你本app的域名。
    expiresDatecookie的過期時間,GMT格式。如果沒有指定或者設置為0,則產生新的cookie。
    httpOnlyBoolean這個cookie只能被web服務器獲取的標示。
    maxAgeString是設置過去時間的方便選項,其為過期時間到當前時間的毫秒值。
    pathStringcookie的路徑。默認值是/。
    secureBoolean標示這個cookie只用被HTTPS協議使用。
    signedBoolean指示這個cookie應該是簽名的。

    res.cookie()所作的都是基于提供的options參數來設置Set-Cookie頭部。沒有指定任何的options,那么默認值在RFC6265中指定。

    使用實例:

  • res.cookie('name', 'tobi', {'domain':'.example.com', 'path':'/admin', 'secure':true});
  • res.cookie('remenberme', '1', {'expires':new Date(Date.now() + 90000), 'httpOnly':true});
  • maxAge是一個方便設置過期時間的方便的選項,其以當前時間開始的毫秒數來計算。下面的示例和上面的第二條功效一樣。

  • res.cookie('rememberme', '1', {'masAge':90000}, "httpOnly":true);
  • 你可以設置傳遞一個對象作為value的參數。然后其將被序列化為Json字符串,被bodyParser()中間件解析。

  • res.cookie('cart', {'items':[1, 2, 3]});
  • res.cookie('cart', {'items':[1, 2, 3]}, {'maxAge':90000});
  • 當我們使用cookie-parser中間件的時候,這個方法也支持簽名的cookie。簡單地,在設置options時包含signed選項為true。然后res.cookie()將使用傳遞給cookieParser(secret)的密鑰來簽名這個值。

  • res.cookie('name', 'tobi', {'signed':true});
  • res.clearCookie(name [,options])

    根據指定的name清除對應的cookie。更多關于options對象可以查閱res.cookie()。

  • res.cookie('name', 'tobi', {'path':'/admin'});
  • res.clearCookie('name', {'path':'admin'});
  • res.download(path, [,filename], [,fn])

    傳輸path指定文件作為一個附件。通常,瀏覽器提示用戶下載。默認情況下,Content-Disposition頭部"filename="的參數為path(通常會出現在瀏覽器的對話框中)。通過指定filename參數來覆蓋默認值。?
    當一個錯誤發生時或者傳輸完成,這個方法將調用fn指定的回調方法。這個方法使用res.sendFile()來傳輸文件。

  • res.download('/report-12345.pdf');
  • res.download('/report-12345.pdf', 'report.pdf');
  • res.download('report-12345.pdf', 'report.pdf', function(err) {
  • // Handle error, but keep in mind the response may be partially-sent
  • // so check res.headersSent
  • if (err) {
  • } else {
  • // decrement a download credit, etc.
  • }
  • });
  • res.end([data] [, encoding])

    結束本響應的過程。這個方法實際上來自Node核心模塊,具體的是response.end() method of http.ServerResponse。?
    用來快速結束請求,沒有任何的數據。如果你需要發送數據,可以使用res.send()和res.json()這類的方法。

  • res.end();
  • res.status(404).end();
  • res.format(object)

    進行內容協商,根據請求的對象中AcceptHTTP頭部指定的接受內容。它使用req.accepts()來選擇一個句柄來為請求服務,這些句柄按質量值進行排序。如果這個頭部沒有指定,那么第一個方法默認被調用。當不匹配時,服務器將返回406"Not Acceptable",或者調用default回調。?
    Content-Type請求頭被設置,當一個回調方法被選擇。然而你可以改變他,在這個方法中使用這些方法,比如res.set()或者res.type()。?
    下面的例子,將回復{"message":"hey"},當請求的對象中Accept頭部設置成"application/json"或者"*/json"(不過如果是*/*,然后這個回復就是"hey")。

  • res.format({
  • 'text/plain':function() {
  • res.send('hey')'
  • },
  • 'text/html':function() {
  • res.send('<p>hey</p>');
  • },
  • 'application/json':function() {
  • res.send({message:'hey'});
  • },
  • 'default':function() {
  • res.status(406).send('Not Acceptable');
  • }
  • })
  • 除了規范化的MIME類型之外,你也可以使用拓展名來映射這些類型來避免冗長的實現:

  • res.format({
  • text:function() {
  • res.send('hey');
  • },
  • html:function() {
  • res.send('<p>hey</p>');
  • },
  • json:function() {
  • res.send({message:'hey'});
  • }
  • })
  • res.get(field)

    返回field指定的HTTP響應的頭部。匹配是區分大小寫。

  • res.get('Content-Type');
  • // => "text/plain"
  • res.json([body])

    發送一個json的響應。這個方法和將一個對象或者一個數組作為參數傳遞給res.send()方法的效果相同。不過,你可以使用這個方法來轉換其他的值到json,例如null,undefined。(雖然這些都是技術上無效的JSON)。

  • res.json(null);
  • res.json({user:'tobi'});
  • res.status(500).json({error:'message'});
  • res.jsonp([body])

    發送一個json的響應,并且支持JSONP。這個方法和res.json()效果相同,除了其在選項中支持JSONP回調。

  • res.jsonp(null)
  • // => null
  • res.jsonp({user:'tobi'})
  • // => {"user" : "tobi"}
  • res.status(500).jsonp({error:'message'})
  • // => {"error" : "message"}
  • 默認情況下,jsonp的回調方法簡單寫作callback。可以通過jsonp callback name設置來重寫它。?
    下面是一些例子使用JSONP響應,使用相同的代碼:

  • // ?callback=foo
  • res.jsonp({user:'tobo'})
  • // => foo({"user":"tobi"})
  • app.set('jsonp callback name', 'cb')
  • // ?cb=foo
  • res.status(500).jsonp({error:'message'})
  • // => foo({"error":"message"})
  • 連接這些links,links是以傳入參數的屬性形式提供,連接之后的內容用來填充響應的Link HTTP頭部。

  • res.links({
  • next:'http://api.example.com/users?page=2',
  • last:'http://api.example.com/user?page=5'
  • });
  • 效果:

  • Link:<http://api.example.com/users?page=2>;rel="next",
  • <http://api.example.com/users?page=5>;rel="last"
  • res.location(path)

    設置響應的LocationHTTP頭部為指定的path參數。

  • res.location('/foo/bar');
  • res.location('http://example.com');
  • res.location('back');
  • 當path參數為back時,其具有特殊的意義,其指定URL為請求對象的Referer頭部指定的URL。如果請求中沒有指定,那么其即為"/"。

    Express傳遞指定的URL字符串作為回復給瀏覽器響應中的Location頭部的值,不檢測和操作,除了當是back這個case時。瀏覽器有推導預期URL從當前的URL或者指定的URL,和在Location指定的URL的責任;相應地重定向它。(我也不知道翻譯的什么...)

    res.redirect([status,] path)

    重定向來源于指定path的URL,以及指定的HTTP status codestatus。如果你沒有指定status,status code默認為"302 Found"。

  • res.redirect('/foo/bar');
  • res.redirect('http://example.com');
  • res.redirect(301, 'http://example.com');
  • res.redirect('../login');
  • 重定向也可以是完整的URL,來重定向到不同的站點。

  • res.redirect('http://google.com');
  • 重定向也可以相對于主機的根路徑。比如,如果程序的路徑為http://example.com/admin/post/new,那么下面將重定向到http://example.com/admim:

  • res.redirect('/admin');
  • 重定向也可以相對于當前的URL。比如,來之于http://example.com/blog/admin/(注意結尾的/),下面將重定向到http://example.com/blog/admin/post/new。

  • res.redirect('post/new');
  • 如果來至于http://example.com/blog/admin(沒有尾部/),重定向post/new,將重定向到http://example.com/blog/post/new。如果你覺得上面很混亂,可以把路徑段認為目錄(有'/')或者文件,這樣是可以的。相對路徑的重定向也是可以的。如果你當前的路徑為http://example.com/admin/post/new,下面的操作將重定向到http://example.com/admin/post:

  • res.redirect('..');
  • back將重定向請求到referer,當沒有referer的時候,默認為/。

  • res.redirect('back');
  • res.render(view [, locals] [, callback])

    渲染一個視圖,然后將渲染得到的HTML文檔發送給客戶端。可選的參數為:

    • locals,定義了視圖本地參數屬性的一個對象。
    • callback,一個回調方法。如果提供了這個參數,render方法將返回錯誤和渲染之后的模板,并且不自動發送響應。當有錯誤發生時,可以在這個回調內部,調用next(err)方法。

    本地變量緩存使能視圖緩存。在開發環境中緩存視圖,需要手動設置為true;視圖緩存在生產環境中默認開啟。

  • // send the rendered view to the client
  • res.render('index');
  • // if a callback is specified, the render HTML string has to be sent explicitly
  • res.render('index', function(err, html) {
  • res.send(html);
  • });
  • // pass a local variable to the view
  • res.render('user', {name:'Tobi'}, function(err, html) {
  • // ...
  • });
  • res.send([body])

    發送HTTP響應。?
    body參數可以是一個Buffer對象,一個字符串,一個對象,或者一個數組。比如:

  • res.send(new Buffer('whoop'));
  • res.send({some:'json'});
  • res.send('<p>some html</p>');
  • res.status(404).send('Sorry, we cannot find that!');
  • res.status(500).send({ error: 'something blew up' });
  • 對于一般的非流請求,這個方法可以執行許多有用的的任務:比如,它自動給Content-LengthHTTP響應頭賦值(除非先前定義),也支持自動的HEAD和HTTP緩存更新。?
    當參數是一個Buffer對象,這個方法設置Content-Type響應頭為application/octet-stream,除非事先提供,如下所示:

  • res.set('Content-Type', 'text/html');
  • res.send(new Buffer('<p>some html</p>'));
  • 當參數是一個字符串,這個方法設置Content-Type響應頭為text/html:

  • res.send('<p>some html</p>');
  • 當參數是一個對象或者數組,Express使用JSON格式來表示:

  • res.send({user:'tobi'});
  • res.send([1, 2, 3]);
  • res.sendFile(path [, options] [, fn])

    res.sendFile()從Express v4.8.0開始支持。

    傳輸path指定的文件。根據文件的擴展名設置Content-TypeHTTP頭部。除非在options中有關于root的設置,path一定是關于文件的絕對路徑。?
    下面的表提供了options參數的細節:

    屬性描述默認值可用版本
    maxAge設置Cache-Control的max-age屬性,格式為毫秒數,或者是ms format的一串字符串0?
    root相對文件名的根目錄??
    lastModified設置Last-Modified頭部為此文件在系統中的最后一次修改時間。設置false來禁用它Enable4.9.0+
    headers一個對象,包含了文件所在的sever的HTTP頭部。(不知道怎么翻譯了)??
    dotfiles是否支持點開頭文件名的選項。可選的值"allow","deny","ignore""ignore"?

    當傳輸完成或者發生了什么錯誤,這個方法調用fn回調方法。如果這個回調參數指定了和一個錯誤發生,回調方法必須明確地通過結束請求-響應循環或者傳遞控制到下個路由來處理響應過程。?
    下面是使用了所有參數的使用res.sendFile()的例子:

  • app.get('/file/:name', function(req, res, next) {
  • var options = {
  • root:__dirname + '/public',
  • dotfile:'deny',
  • headers:{
  • 'x-timestamp':Date.now(),
  • 'x-sent':true
  • }
  • };
  • var fileName = req.params.name;
  • res.sendFile(fileName, options, function(err) {
  • if (err) {
  • console.log(err);
  • res.status(err.status).end();
  • }
  • else {
  • console.log('sent', fileName);
  • }
  • });
  • });
  • res.sendFile提供了文件服務的細粒度支持,如下例子說明:

  • app.get('/user/:uid/photos/:file', function(req, res) {
  • var uid = req.params.uid
  • , file = req.params.file;
  • req.user.mayViewFilesFrom(uid, function(yes) {
  • if (yes) {
  • res.sendFile('/upload/' + uid + '/' + file);
  • }
  • else {
  • res.status(403).send('Sorry! you cant see that.');
  • }
  • });
  • })
  • 獲取更多信息,或者你有問題或者關注,可以查閱send。

    res.sendStatus(statusCode)

    設置響應對象的HTTP status code為statusCode并且發送statusCode的相應的字符串形式作為響應的Body。

  • res.sendStatus(200); // equivalent to res.status(200).send('OK');
  • res.sendStatus(403); // equivalent to res.status(403).send('Forbidden');
  • res.sendStatus(404); // equivalent to res.status(404).send('Not Found');
  • res.sendStatus(500); // equivalent to res.status(500).send('Internal Server Error')
  • 如果一個不支持的狀態被指定,這個HTTP status依然被設置為statusCode并且用這個code的字符串作為Body。

  • res.sendStatus(2000); // equivalent to res.status(2000).send('2000');
  • More about HTTP Status Codes

    res.set(field [, value])

    設置響應對象的HTTP頭部field為value。為了一次設置多個值,那么可以傳遞一個對象為參數。

  • res.set('Content-Type', 'text/plain');
  • res.set({
  • 'Content-Type':'text/plain',
  • 'Content-Length':'123',
  • 'ETag':'123456'
  • })
  • 其和res.header(field [,value])效果一致。

    res.status(code)

    使用這個方法來設置響應對象的HTTP status。其是Node中response.statusCode的一個連貫性的別名。

  • res.status(403).end();
  • res.status(400).send('Bad Request');
  • res.status(404).sendFile('/absolute/path/to/404.png');
  • res.type(type)

    設置Content-TypeHTTP頭部為MIME type,如果這個指定的type能夠被mime.lookup確定。如果type包含/字符,那么設置Content-Type為type(我已經暈了)。

  • res.type('.html'); // => 'text/html'
  • res.type('html'); // => 'text/html'
  • res.type('json'); // => 'application/json'
  • res.type('application/json'); // => 'application/json'
  • res.type('png'); // => image/png:
  • res.vary(field)

    設置Vary響應頭為field,如果已經不在那里。(不懂什么意思)

  • res.vary('User-Agent').render('docs');
  • Router

    一個router對象是一個單獨的實例關于中間件和路由。你可以認為其是一個"mini-application"(迷你程序),其具有操作中間件和路由方法的能力。每個Express程序有一個內建的app路由。?
    路由自身表現為一個中間件,所以你可以使用它作為app.use()方法的一個參數或者作為另一個路由的use()的參數。?
    頂層的express對象有一個Router()方法,你可以使用Router()來創建一個新的router對象。

    Router([options])

    如下,可以創建一個路由:

  • var router = express.Router([options]);
  • options參數可以指定路由的行為,其有下列選擇:

    屬性描述默認值可用性
    caseSensitive是否區分大小寫默認不啟用。對待/Foo和/foo一樣。?
    mergeParams保存父路由的res.params。如果父路由參數和子路由參數沖突,子路由參數優先。false4.5.0+
    strict使能嚴格路由。默認不啟用,/foo和/foo/被路由一樣對待處理?

    你可以將router當作一個程序,可以在其上添加中間件和HTTP路由方法(例如get,put,post等等)。

  • // invoked for any requests passed to this router
  • router.use(function(req, res, next) {
  • // .. some logic here .. like any other middleware
  • next();
  • });
  • // will handle any request that ends in /events
  • // depends on where the router is "use()'d"
  • router.get('/events', function(req, res, next) {
  • // ..
  • });
  • 你可以在一個特別的根URL上掛載一個路由,這樣你就以將你的各個路由放到不同的文件中或者甚至是mini的程序。

  • // only requests to /calendar/* will be sent to our "router"
  • app.use('/calendar', router);
  • Methods

    router.all(path, [callback, ...] callback)

    這個方法和router.METHOD()方法一樣,除了這個方法會匹配所有的HTTP動作。?
    這個方法對想映射全局的邏輯處理到特殊的路徑前綴或者任意匹配是十分有用的。比如,如果你放置下面所示的這個路由在其他路由的前面,那么其將要求從這個點開始的所有的路由進行驗證操作和自動加載用戶信息。記住,這些全局的邏輯操作,不需要結束請求響應周期:loaduser可以執行一個任務,然后調用next()來將執行流程移交到隨后的路由。

  • router.all('*', requireAuthentication, loadUser);
  • 相等的形式:

  • router.all('*', requireAuthentication)
  • router.all('*', loadUser);
  • 這是一個白名單全局功能的例子。這個例子很像前面的,不過其僅僅作用于以/api開頭的路徑:

  • router.all('/api/*', requireAuthentication);
  • router.METHOD(path, [callback, ...] callback)

    router.METHOD()方法提供了路由方法在Express中,這里的METHOD是HTTP方法中的一個,比如GET,PUT,POST等等,但router中的METHOD是小寫的。所以,實際的方法是router.get(),router.put(),router.post()等等。?
    你可以提供多個回調函數,它們的行為和中間件一樣,除了這些回調可以通過調用next('router')來繞過剩余的路由回調。你可以使用這個機制來為一個路由設置一些前提條件,如果請求沒有滿足當前路由的處理條件,那么傳遞控制到隨后的路由。?
    下面的片段可能說明了最簡單的路由定義。Experss轉換path字符串為正則表達式,用于內部匹配傳入的請求。在匹配的時候,是不考慮Query strings,例如,"GET /"將匹配下面的路由,"GET /?name=tobi"也是一樣的。

  • router.get('/', function(req, res) {
  • res.send('Hello World');
  • });
  • 如果你對匹配的path有特殊的限制,你可以使用正則表達式,例如,下面的可以匹配"GET /commits/71dbb9c"和"GET /commits/71bb92..4c084f9"。

  • router.get(/^\/commits\/(\w+)(?:\.\.(\w+))?$/, function(req, res) {
  • var from = req.params[0];
  • var to = req.params[1];
  • res.send('commit range ' + from + '..' + to);
  • });
  • router.param(name, callback)

    給路由參數添加回調觸發器,這里的name是參數名,function是回調方法。回調方法的參數按序是請求對象,響應對象,下個中間件,參數值和參數名。雖然name在技術上是可選的,但是自Express V4.11.0之后版本不推薦使用(見下面)。

    不像app.param(),router.param()不接受一個數組作為路由參數。

    例如,當:user出現在路由路徑中,你可以映射用戶加載的邏輯處理來自動提供req.user給這個路由,或者對輸入的參數進行驗證。

  • router.param('user', function(req, res, next, id) {
  • User.find(id, function(error, user) {
  • if (err) {
  • next(err);
  • }
  • else if (user){
  • req.user = user;
  • } else {
  • next(new Error('failed to load user'));
  • }
  • });
  • });
  • 對于Param的回調定義的路由來說,他們是局部的。它們不會被掛載的app或者路由繼承。所以,定義在router上的param回調只有是在router上的路由具有這個路由參數時才起作用。?
    在定義param的路由上,param回調都是第一個被調用的,它們在一個請求-響應循環中都會被調用一次并且只有一次,即使多個路由都匹配,如下面的例子:

  • router.param('id', function(req, res, next, id) {
  • console.log('CALLED ONLY ONCE');
  • next();
  • });
  • router.get('/user/:id', function(req, res, next) {
  • console.log('although this matches');
  • next();
  • });
  • router.get('/user/:id', function(req, res) {
  • console.log('and this mathces too');
  • res.end();
  • });
  • 當GET /user/42,得到下面的結果:

  • CALLED ONLY ONCE
  • although this matches
  • and this matches too
  • `

    下面章節描述的router.param(callback)在v4.11.0之后被棄用。

    通過只傳遞一個回調參數給router.param(name, callback)方法,router.param(naem, callback)方法的行為將被完全改變。這個回調參數是關于router.param(name, callback)該具有怎樣的行為的一個自定義方法,這個方法必須接受兩個參數并且返回一個中間件。?
    這個回調的第一個參數就是需要捕獲的url的參數名,第二個參數可以是任一的JavaScript對象,其可能在實現返回一個中間件時被使用。?
    這個回調方法返回的中間件決定了當URL中包含這個參數時所采取的行為。?
    在下面的例子中,router.param(name, callback)參數簽名被修改成了router.param(name, accessId)。替換接受一個參數名和回調,router.param()現在接受一個參數名和一個數字。

  • var express = require('express');
  • var app = express();
  • var router = express.Router();
  • router.param(function(param, option){
  • return function(req, res, next, val) {
  • if (val == option) {
  • next();
  • }
  • else {
  • res.sendStatus(403);
  • }
  • }
  • });
  • router.param('id', 1337);
  • router.get('/user/:id', function(req, res) {
  • res.send('Ok');
  • });
  • app.use(router);
  • app.listen(3000, function() {
  • console.log('Ready');
  • });
  • 在這個例子中,router.param(name. callback)參數簽名保持和原來一樣,但是替換成了一個中間件,定義了一個自定義的數據類型檢測方法來檢測user id的類型正確性。

  • router.param(function(param, validator) {
  • return function(req, res, next, val) {
  • if (validator(val)) {
  • next();
  • }
  • else {
  • res.sendStatus(403);
  • }
  • }
  • });
  • router.param('id', function(candidate) {
  • return !isNaN(parseFloat(candidate)) && isFinite(candidate);
  • });
  • router.route(path)

    返回一個單例模式的路由的實例,之后你可以在其上施加各種HTTP動作的中間件。使用app.route()來避免重復路由名字(因此錯字錯誤)--后面這句不知道說的什么鬼,大概的意思就是避免同一個路徑有兩個路由實例。?
    構建在上面的router.param()例子之上,下面的代碼展示了怎么使用router.route()來指定各種HTTP方法的處理句柄。

  • var router = express.Router();
  • router.param('user_id', function(req, res, next, id) {
  • // sample user, would actually fetch from DB, etc...
  • req.user = {
  • id:id,
  • name:"TJ"
  • };
  • next();
  • });
  • router.route('/users/:user_id')
  • .all(function(req, res, next) {
  • // runs for all HTTP verbs first
  • // think of it as route specific middleware!
  • next();
  • })
  • .get(function(req, res, next) {
  • res.json(req.user);
  • })
  • .put(function(req, res, next) {
  • // just an example of maybe updating the user
  • req.user.name = req.params.name;
  • // save user ... etc
  • res.json(req.user);
  • })
  • .post(function(req, res, next) {
  • next(new Error('not implemented'));
  • })
  • .delete(function(req, res, next) {
  • next(new Error('not implemented'));
  • })
  • 這種方法重復使用單個/usrs/:user_id路徑來添加了各種的HTTP方法。

    router.use([path], [function, ...] function)

    給可選的path參數指定的路徑掛載給定的中間件方法,未指定path參數,默認值為/。?
    這個方法類似于app.use()。一個簡單的例子和用例在下面描述。查閱app.use()獲得更多的信息。?
    中間件就像一個水暖管道,請求在你定義的第一個中間件處開始,順著中間件堆棧一路往下,如果路徑匹配則處理這個請求。

  • var express = require('express');
  • var app = express();
  • var router = express.Router();
  • // simple logger for this router`s requests
  • // all requests to this router will first hit this middleware
  • router.use(function(req, res, next) {
  • console.log('%s %s %s', req.method, req.url, req.path);
  • next();
  • })
  • // this will only be invoked if the path starts with /bar form the mount ponit
  • router.use('/bar', function(req, res, next) {
  • // ... maybe some additional /bar logging ...
  • next();
  • })
  • // always be invoked
  • router.use(function(req, res, next) {
  • res.send('hello world');
  • })
  • app.use('/foo', router);
  • app.listen(3000);
  • 對于中間件function,掛載的路徑是被剝離的和不可見的。關于這個特性主要的影響是對于不同的路徑,掛載相同的中間件可能對代碼不做改動,盡管其前綴已經改變。?
    你使用router.use()定義中間件的順序很重要。中間們是按序被調用的,所以順序決定了中間件的優先級。例如,通常日志是你將使用的第一個中間件,以便每一個請求都被記錄。

  • var logger = require('morgan');
  • router.use(logger());
  • router.use(express.static(__dirname + '/public'));
  • router.use(function(req, res) {
  • res.send('Hello');
  • });
  • 現在為了支持你不希望記錄靜態文件請求,但為了繼續記錄那些定義在logger()之后的路由和中間件。你可以簡單的將static()移動到前面來解決:

  • router.use(express.static(__dirname + '/public'));
  • router.use(logger());
  • router.use(function(req, res){
  • res.send('Hello');
  • });
  • 另外一個確鑿的例子是從不同的路徑托管靜態文件,你可以將./public放到前面來獲得更高的優先級:

  • app.use(express.static(__dirname + '/public'));
  • app.use(express.static(__dirname + '/files'));
  • app.use(express.static(__dirname + '/uploads'));
  • router.use()方法也支持命名參數,以便你的掛載點對于其他的路由而言,可以使用命名參數來進行預加載,這樣做是很有益的。

    轉載于:https://www.cnblogs.com/younger-plant/p/5547843.html

    總結

    以上是生活随笔為你收集整理的nodejs 框架 中文express 4.xxx中文API手册的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    av免费在线看网站 | 天天爽天天搞 | 亚洲 成人 一区 | 婷婷在线五月 | 国产精品自产拍在线观看蜜 | 黄色免费高清视频 | 亚洲第一成网站 | 91视频观看免费 | 久草国产精品 | 国产精品久久久久一区二区三区 | 婷婷综合久久 | 97品白浆高清久久久久久 | 91黄在线看| 久一在线 | 成人一区二区三区在线观看 | 午夜影院先 | 日韩欧美91 | www激情网 | 亚州精品天堂中文字幕 | 综合久久精品 | 黄色小网站免费看 | 国产又粗又猛又黄视频 | 99精品在线视频播放 | 黄色www| 久久免费国产 | 久久超碰99 | 99视频精品全部免费 在线 | 麻豆高清免费国产一区 | 中文字幕一区二区三区在线播放 | 99综合影院在线 | 日本爱爱免费 | 久久精品一二三区白丝高潮 | 伊人婷婷网 | 欧美精品中文字幕亚洲专区 | 国产精品中文 | 亚洲妇女av | 亚洲 欧美 综合 在线 精品 | 国产在线视频资源 | 国产99免费视频 | 五月婷婷av | 开心色激情网 | 精品久久久久久国产 | 天天操夜夜操夜夜操 | 午夜电影 电影 | 九九热.com| 久草在线视频在线 | 日本久久99 | 黄色小说视频在线 | 日日日操| 日韩欧美在线播放 | 亚洲免费公开视频 | 超级碰碰碰视频 | 国产不卡一 | 亚洲精品小视频 | 在线a人片免费观看视频 | 久久污视频 | 国产资源网 | 在线免费视频 你懂得 | 国产欧美在线一区二区三区 | 免费观看一级视频 | 久久免费看av | 婷婷激情五月 | 在线99视频 | 99热最新精品 | 久久中文字幕视频 | ww亚洲ww亚在线观看 | 欧美精品久久久久久久久久 | 成人黄色电影在线播放 | 久久中文字幕视频 | 欧美激情精品久久久久久免费 | 欧美xxxxx在线视频 | 中文字幕黄色网 | 欧美精品亚洲精品日韩精品 | 亚洲综合丁香 | 丁香高清视频在线看看 | 国产精品久免费的黄网站 | 久草免费电影 | 日韩欧美高清免费 | 最新国产在线视频 | 国产色区 | 在线看中文字幕 | 亚洲 欧美 国产 va在线影院 | 精品视频在线免费 | 91丨九色丨国产在线观看 | 成年一级片 | 国产精品99久久久久久久久久久久 | 国产在线国偷精品产拍免费yy | 国产一区二区中文字幕 | 免费黄a | 婷婷丁香九月 | 日本视频精品 | 99国内精品久久久久久久 | 日韩在线观看免费 | 亚洲国产精品va在线 | 人人澡视频 | 在线日本v二区不卡 | 免费看国产一级片 | 欧美成人h版在线观看 | 91精品毛片 | 精品亚洲免费视频 | 在线观看视频精品 | 亚洲天天在线日亚洲洲精 | 91精品视频免费看 | 看av免费 | 碰天天操天天 | 97看片吧| 麻豆传媒在线免费看 | av短片在线观看 | 黄色avwww| 99亚洲精品视频 | 日韩在线观看你懂的 | 午夜精品一区二区国产 | 久久国产精品二国产精品中国洋人 | 久章草在线 | 激情婷婷综合网 | 中文字幕在线观看免费高清电影 | 久久国产精品免费一区二区三区 | 亚洲狠狠操 | 深爱婷婷网 | 99国产精品久久久久久久久久 | 青草视频在线 | 五月婷婷激情综合网 | 日韩电影一区二区在线 | 黄色a级片在线观看 | 久久久久久久久久久久国产精品 | 亚洲国产高清在线观看视频 | 欧美性黄网官网 | 激情五月激情综合网 | 日韩综合一区二区 | 综合色站 | 99精品久久久久久久 | 伊人狠狠色 | 成人av电影在线观看 | 国产精品99爱 | 亚洲精品久久久蜜桃直播 | 91精品国产成人观看 | 波多野结衣精品 | 亚洲无人区小视频 | 91九色pron| 四虎免费在线观看视频 | 国产亚洲视频在线免费观看 | 亚洲欧美日韩在线一区二区 | 精品亚洲二区 | 国产一级免费观看视频 | 国产精品久久久久av | 亚洲视频在线观看免费 | 美女黄频在线观看 | 欧美性性网 | 四虎在线视频 | 久久精品首页 | 久久超级碰视频 | 美女av免费看 | 欧美精品v国产精品v日韩精品 | 亚洲成aⅴ人在线观看 | 91av综合| 日韩久久网站 | 欧美在线你懂的 | 欧美激情综合色 | 黄a网 | 亚洲2019精品 | 97国产超碰在线 | 日日夜夜精品免费观看 | 中文在线8资源库 | 久久久久久网址 | 亚洲国产剧情 | 天天干,夜夜爽 | 久久尤物电影视频在线观看 | 人人爽人人爽人人片av | av东方在线| 日日摸日日添夜夜爽97 | 在线视频观看成人 | 久久9精品 | 97超碰色 | 国产精品免费久久久久影院仙踪林 | 国产成人精品一二三区 | 国产女人40精品一区毛片视频 | 狠狠干夜夜操 | 国产天天爽 | 成人性生交视频 | 久久免费视频5 | 色七七亚洲影院 | 久久精品国产精品亚洲 | 6080yy午夜一二三区久久 | 成人精品视频久久久久 | 天天爽夜夜爽人人爽曰av | 久色婷婷 | 国产剧情一区 | 97超碰人人爱 | 成人a视频在线观看 | 国产成人av免费在线观看 | 国产在线观看一 | 午夜视频在线观看一区二区三区 | 97视频入口免费观看 | 国产精品久久电影观看 | 日韩女同av| 日韩精品一区二区三区高清免费 | 伊人六月 | 黄色片网站大全 | 久热国产视频 | 久草视频在线免费看 | 精品无人国产偷自产在线 | 国产精品久久久久久久久久尿 | 九九热在线精品 | 婷婷中文字幕在线观看 | 国产精品久久99综合免费观看尤物 | 91人人干 | 久久在线观看 | 成年人黄色大片在线 | 蜜臀精品久久久久久蜜臀 | 91视频在线免费看 | 一本一本久久a久久精品牛牛影视 | 色噜噜日韩精品一区二区三区视频 | 国产午夜精品一区二区三区四区 | 91色国产| 波多野结衣在线视频免费观看 | 精品日韩中文字幕 | 国产精品久久久久久久久久久久午夜片 | av成人免费网站 | 一区二区三区高清在线观看 | 久草a视频| 欧美日韩在线免费视频 | 国内精品久久久久影院男同志 | 视频一区视频二区在线观看 | 天天摸夜夜添 | 亚洲视频资源在线 | 欧美一二区视频 | 午夜91在线 | 永久免费在线 | 精品国产_亚洲人成在线 | 日韩av图片| 色综合久久中文综合久久牛 | 久草a在线 | 国产精品淫 | 国产精品永久免费在线 | 精品高清视频 | 久久在线电影 | 丁香久久激情 | 免费观看丰满少妇做爰 | 亚洲最新毛片 | 在线观看视频你懂的 | 最新av在线网站 | av在线精品 | 九草在线观看 | 五月婷婷在线观看视频 | 久久av免费电影 | 在线黄色免费 | 99在线免费观看视频 | 99久久精品免费看国产免费软件 | 亚洲免费av网站 | a级国产片 | 在线观看第一页 | 国产日韩视频在线播放 | 精品在线观看一区二区三区 | 午夜性盈盈 | 丝袜美腿av | 99热在| 日韩大片在线播放 | 美国人与动物xxxx | 久久综合色8888 | 久久久久亚洲最大xxxx | 日本在线中文 | 国产成人一区二区精品非洲 | 国产精品九色 | 欧美日韩国产mv | 国产亚洲一区二区三区 | 97操操操| 国产黄色一级片 | 二区三区在线视频 | 国产a国产 | 日韩av黄 | 99久久精品免费看国产麻豆 | 在线观看一区视频 | 日韩中文字幕视频在线观看 | 国产免费视频在线 | 在线亚洲精品 | 亚洲精品视频免费 | 婷婷免费在线视频 | 中文字幕在线观看免费高清电影 | 丁香 婷婷 激情 | 亚州av免费 | 福利视频网站 | 中文字幕a∨在线乱码免费看 | 欧美电影在线观看 | 亚洲综合激情 | 国产一级电影 | 免费av一级电影 | 久久免费电影网 | 日韩在线 一区二区 | 91成品人影院 | 中文字幕在线观看网址 | 久久首页 | 国产成人精品a | 国产又粗又猛又黄又爽的视频 | 日韩av成人在线 | www五月天 | 91片黄在线观看 | 国产高清视频 | 日日操狠狠干 | 500部大龄熟乱视频使用方法 | 久久久福利视频 | 国产高清在线精品 | 欧美日本高清视频 | 日本视频久久久 | 国产一区二区三区午夜 | 97网在线观看 | 麻花传媒mv免费观看 | 在线播放 亚洲 | 亚洲专区欧美专区 | 国产一卡二卡在线 | 一级黄色片在线免费看 | 天天综合色 | 91大神电影 | 狠狠躁日日躁 | 手机在线永久免费观看av片 | 久久久免费毛片 | 国产精品免费大片视频 | 国产理论一区二区三区 | 日韩欧美精品在线视频 | 天天视频亚洲 | 中文字幕久久精品一区 | 永久免费毛片在线观看 | 亚洲一区二区三区毛片 | 国产亚洲精品美女久久 | 日韩久久一区二区 | 九九热精品视频在线观看 | www.啪啪.com | 日韩精品最新在线观看 | av+在线播放在线播放 | 夜色成人av | 国产美女黄网站免费 | 99精品黄色 | 国产视频一区在线 | 伊人电影在线观看 | 欧美整片sss| 国产精品美女www爽爽爽视频 | 中文字幕亚洲精品日韩 | 毛片网站免费在线观看 | 一区二区视频电影在线观看 | 久久久久国产精品免费免费搜索 | 久99久精品视频免费观看 | av免费观看高清 | 一级电影免费在线观看 | 久久曰视频 | 五月开心婷婷网 | 国产精品久久久久久久久免费 | 欧美日韩国产综合网 | 在线观看视频免费播放 | 久久国产精品99久久久久久老狼 | 日韩h在线观看 | 视频在线观看一区 | 黄色福利| 黄色大片视频网站 | 日本aa在线 | 国产精品理论片 | 国产午夜av | 久久久国产精品成人免费 | 色资源在线观看 | 日日夜夜91 | 欧美性生活小视频 | 国产精品嫩草影院99网站 | 色综合久久久 | 中文字幕在线观看免费观看 | 五月婷婷开心 | 久久久精品99 | 天天色天天爱天天射综合 | 国产精品视频地址 | 亚洲国产精品免费 | 国产免费av一区二区三区 | 久久久国产精品视频 | 日韩视频在线观看视频 | 四虎国产精品永久在线国在线 | 激情欧美一区二区三区免费看 | 最新日韩在线观看视频 | 黄色av一区二区 | 日韩欧美视频二区 | 国产精品手机在线观看 | 日本99干网 | 六月色丁 | 久久久久一区二区三区四区 | 日韩av网页 | 久草视频在线播放 | 国产专区在线视频 | 国产亚洲精品福利 | 国产激情小视频在线观看 | 国产精品久久久久久一区二区三区 | 日本性生活一级片 | 成人97人人超碰人人99 | 国精产品999国精产品视频 | 五月婷婷中文网 | 狠狠躁天天躁 | 久久久久久久久网站 | 亚洲国产免费看 | 色偷偷av男人天堂 | 天天在线免费视频 | 伊人天天 | 国产精品影音先锋 | 婷婷综合五月天 | 91成人在线免费观看 | 色综合久久久 | 欧美日韩中字 | 国产一区二区在线看 | 在线黄色av电影 | 国产成年免费视频 | 美女av在线免费 | 日韩va欧美va亚洲va久久 | 香蕉97视频观看在线观看 | 成人久久精品 | 九九热视频在线免费观看 | 欧美色一色| 最近的中文字幕大全免费版 | 久久五月激情 | 偷拍精偷拍精品欧洲亚洲网站 | 美国三级黄色大片 | 91精品啪 | 欧美性天天 | 日韩网站免费观看 | 操夜夜操| 国产成人精品一区二区在线 | 日韩中文字幕91 | 亚洲精品综合一区二区 | 久久久久久久久久久电影 | 极品嫩模被强到高潮呻吟91 | 2019免费中文字幕 | 亚洲第一伊人 | 免费情缘 | 香蕉视频久久久 | 亚洲h色精品 | 99在线热播精品免费99热 | 久久精品99久久 | 国产91精品高清一区二区三区 | 成人久久 | 日韩性色 | 九九热只有这里有精品 | 中文字幕 91 | 5月丁香婷婷综合 | av永久网址| 国产自制av| 亚洲久草网 | 欧美精品久 | 中文在线字幕免 | 在线观看免费中文字幕 | 性色av免费在线观看 | 麻豆传媒在线免费看 | 亚洲欧美激情插 | 亚洲最新视频在线播放 | 中文理论片 | 美女视频黄在线观看 | 国产69精品久久久久9999apgf | 中文字幕一区2区3区 | 国产视频美女 | 国产一区二区午夜 | 日本女人的性生活视频 | 奇米影视四色8888 | 成人a在线 | 九色最新网址 | 成人午夜影院在线观看 | 1024手机看片国产 | 欧美激情综合五月色丁香小说 | 亚洲久在线| 8090yy亚洲精品久久 | 国产精品免费观看视频 | 欧美少妇影院 | 亚洲电影av在线 | 色婷婷综合久色 | 日韩电影中文,亚洲精品乱码 | 国产在线观看国语版免费 | 99视频黄 | 亚洲一区二区视频在线 | 开心激情综合网 | 伊人日日干 | 天天五月天色 | 国产探花| 92av视频 | 国产 日韩 在线 亚洲 字幕 中文 | 国产色女人 | 成人污视频在线观看 | 成人免费毛片aaaaaa片 | 青青河边草手机免费 | 91精品在线免费 | 亚洲毛片久久 | 九九九热精品免费视频观看网站 | 国产黄色a| 国产老太婆免费交性大片 | 精品亚洲一区二区三区 | 国产主播大尺度精品福利免费 | 天天草综合 | 国内久久久久 | 久久美女免费视频 | 999久久久欧美日韩黑人 | 97国产大学生情侣白嫩酒店 | 最近免费中文视频 | 国产精品久久久久久久av电影 | 国产精品亚洲人在线观看 | av中文字幕免费在线观看 | 日本精品视频在线观看 | 色综合激情久久 | 字幕网av | 国产91免费在线 | 欧美小视频在线 | 国产流白浆高潮在线观看 | 一区二区三区在线影院 | 伊人久久电影网 | 五月婷婷视频 | 成人黄色小视频 | 天天操天天操天天操天天操天天操天天操 | 欧美日韩在线精品一区二区 | 久久精品综合一区 | 91精品在线观看视频 | 日本视频精品 | 日本在线观看中文字幕无线观看 | 欧美成人日韩 | 成人黄大片 | 麻豆视频免费入口 | 日日干日日色 | 日韩精品一区二区免费 | 色吧av色av | 日韩精品aaa| 在线va视频| 91大神一区二区三区 | 国产精品99精品久久免费 | 玖草在线观看 | 欧美精品免费一区二区 | 久久精品视频在线观看免费 | 麻豆国产精品一区二区三区 | 日日爽夜夜操 | 精品福利av| 国产亚洲精品中文字幕 | 欧美日韩啪啪 | 欧美日韩在线视频免费 | 天天爱天天插 | 亚洲第一中文字幕 | 日韩av网站在线播放 | 一区二区三区日韩视频在线观看 | 在线观看成人 | 欧美成人aa| 在线观看成人毛片 | 日韩成人在线免费观看 | 午夜99| 色资源在线| 91久久精品日日躁夜夜躁国产 | 一级一级一片免费 | 国产 欧美 日产久久 | 激情欧美一区二区三区免费看 | 欧美日韩69 | 中文字幕国产一区二区 | 婷婷开心久久网 | av免费看在线 | 日韩免费播放 | 99热在线国产| 日韩影视在线观看 | 视频一区二区精品 | 亚洲黄色精品 | 亚洲激情在线视频 | 久久国内精品 | 国内精品免费久久影院 | 亚洲天堂色婷婷 | 亚洲闷骚少妇在线观看网站 | 久久久久久伊人 | 在线国产视频观看 | 天天干,天天干 | 亚洲乱码在线观看 | 丝袜美腿在线播放 | 五月天六月婷 | 天堂资源在线观看视频 | 亚洲视频在线免费观看 | 日本黄色免费播放 | 精品美女久久久久久免费 | 精品久久久久久一区二区里番 | 国产在线欧美 | 韩国av免费在线 | 国产精品乱码高清在线看 | 久久亚洲福利 | 久久首页 | 手机av在线免费观看 | 91麻豆免费版 | 99在线免费观看视频 | 日日噜噜噜噜夜夜爽亚洲精品 | 欧美aaa视频 | 91av在线播放视频 | 成人精品在线 | 少妇自拍av | 在线日韩视频 | 久久精品毛片 | 成年人在线看片 | 日韩专区av| 18国产精品白浆在线观看免费 | 精品国产精品一区二区夜夜嗨 | 精品国产亚洲一区二区麻豆 | 精品久久久久久久久久久久久久久久 | 99久久精品免费看国产一区二区三区 | www.黄色网.com | 成人a在线 | 成年人在线免费看 | 九九色在线观看 | 成人av一级片 | 福利av在线| 99在线精品免费视频九九视 | 丁香婷婷基地 | 91免费版在线 | 在线成人免费av | www夜夜操com | 成人观看视频 | 在线久草视频 | 免费视频一二三区 | 国产最新在线观看 | 国产精品 亚洲精品 | 久久精品一二三区 | 视频直播国产精品 | 中文字幕日韩无 | 精品一区二区久久久久久久网站 | 成人av电影在线播放 | 右手影院亚洲欧美 | 天无日天天操天天干 | 怡红院av久久久久久久 | 午夜私人影院久久久久 | 97操操操| 国产一区在线播放 | 久久草网站 | 最新真实国产在线视频 | 一区二区三区手机在线观看 | 亚洲在线网址 | 欧美一级专区免费大片 | а天堂中文最新一区二区三区 | 四虎国产精品免费 | 2023年中文无字幕文字 | 中文字幕在线观看视频免费 | 免费三级骚 | 精品久久久久久综合日本 | 天天干天天操天天操 | 日韩资源在线 | 国产高清成人在线 | 国产综合精品一区二区三区 | 99人久久精品视频最新地址 | 成人激情开心网 | 黄色片视频免费 | 色欲综合视频天天天 | 欧美亚洲免费在线一区 | 麻豆系列在线观看 | 国产精品午夜在线 | 韩国av免费 | 中文国产成人精品久久一 | 天天拍天天干 | 人人讲下载 | 亚洲无毛专区 | 亚洲精品9 | 一级黄色片在线免费看 | 一区二区三区在线免费播放 | 日韩网 | 日本高清xxxx | 波多野结衣视频一区二区 | 国内精品久久久久影院优 | 伊人久久影视 | 91中文在线| 97超碰在线免费 | 精品欧美乱码久久久久久 | 国产久视频 | 国产精品一区二区你懂的 | 黄色一区二区在线观看 | 天天躁日日躁狠狠躁av中文 | 久久久久综合精品福利啪啪 | 久久这里精品视频 | av免费电影网站 | 国产区免费在线 | 中文字幕在线观看完整版电影 | 亚洲男女精品 | 天天综合网在线观看 | 欧美性大胆 | 午夜久久网站 | 高清av中文字幕 | 日本久久免费电影 | 一区二区三区中文字幕在线观看 | 久久综合在线 | 又紧又大又爽精品一区二区 | 中文字幕 欧美性 | 亚洲人成人99网站 | 四虎免费av | 亚洲在线成人精品 | 国产精品一级视频 | 99久精品视频| 嫩草av在线| 国产一级片视频 | 九九综合在线 | 日本婷婷色 | 精品成人a区在线观看 | 免费av在线播放 | 婷婷丁香花 | 最近中文字幕完整高清 | 九九九九精品 | 久久精品看片 | 日韩剧 | 国产资源站 | 91人人爽久久涩噜噜噜 | 色综合咪咪久久网 | 久久久久免费精品视频 | 中文字幕第一页在线播放 | 亚洲精品麻豆 | 欧美精品网站 | 国产 字幕 制服 中文 在线 | 久久国产精品免费观看 | 99精品影视 | 精品一区二区亚洲 | 久久网址 | 九九久久久久99精品 | 999精品 | 黄色成人91 | 国产黄色大全 | 成人av影院在线观看 | 久草免费在线观看视频 | 激情网五月 | 亚洲男女精品 | 一区二区在线不卡 | 亚洲午夜久久久综合37日本 | 亚洲乱码在线观看 | 国产成人精品综合久久久 | 国产一区欧美二区 | 天天操夜夜想 | 国产精品高潮久久av | 国产精品久久久久久久午夜 | 久久亚洲电影 | 午夜精品福利一区二区 | www.五月天婷婷 | 欧美性粗大hdvideo | 日韩有码欧美 | 精品久久91| 色综合婷婷 | 婷婷六月久久 | 久久资源在线 | 婷婷六月综合亚洲 | 欧美日韩亚洲在线观看 | 一区二区三区久久精品 | 日本少妇高清做爰视频 | 国产精品久久久久久久久久三级 | 日韩精品一区在线观看 | 外国av网| 国产一区二区精品91 | 麻豆观看 | 911在线 | 日本最新高清不卡中文字幕 | 国产成人精品久久久久 | 日本爱爱免费视频 | 亚洲国产wwwccc36天堂 | 成人a视频在线观看 | 久久久久观看 | 怡红院成人在线 | 激情开心色 | 国产97色 | 久久成年人 | 99久久久成人国产精品 | 国产成人一区二区精品非洲 | 亚洲综合激情 | 成人欧美在线 | 日韩av二区 | 黄色国产高清 | 偷拍精偷拍精品欧洲亚洲网站 | 最近更新好看的中文字幕 | 在线看福利av | 国产黄色片久久 | 四虎国产 | 丁香婷婷社区 | 欧美一级专区免费大片 | 97国产大学生情侣白嫩酒店 | 日批网站在线观看 | 碰天天操天天 | 91在线观看视频 | 99精品99| 精品国产黄色片 | 9992tv成人免费看片 | 97成人精品视频在线播放 | www国产亚洲 | 婷婷丁香自拍 | 人人爱人人爽 | 精品国产伦一区二区三区观看说明 | 久久精品最新 | 中文字幕日本特黄aa毛片 | 国产糖心vlog在线观看 | 91在线精品视频 | 欧美日韩一区二区三区视频 | 国产91免费在线观看 | 国产精品国产自产拍高清av | 日韩综合在线观看 | 一级黄色视屏 | 日本三级中文字幕在线观看 | 国产美腿白丝袜足在线av | 日日操夜 | 欧美性受极品xxxx喷水 | 这里只有精品视频在线观看 | 国产91精品高清一区二区三区 | 在线色吧| 国产四虎在线 | 国产二区免费视频 | 久久久精品在线观看 | 国产最顶级的黄色片在线免费观看 | 手机色站 | 久久久91精品国产一区二区精品 | 日日日日干 | 99热这里有精品 | 韩国三级av在线 | 国产伦精品一区二区三区高清 | 亚洲激情影院 | 四虎免费av | 国产一级在线观看视频 | 91高清视频在线 | 成人cosplay福利网站 | 午夜精品导航 | 亚州av网站 | 在线电影 一区 | 欧美精品一区在线 | 超碰在线公开免费 | 国产成视频在线观看 | 国产偷v国产偷∨精品视频 在线草 | 婷婷综合五月天 | 六月激情久久 | 日日夜夜天天久久 | 免费高清无人区完整版 | 99爱视频在线观看 | 少妇性xxx| 精品天堂av | 狠狠操影视 | www.狠狠操| 五月天天av | 欧美做受高潮1 | 99免费在线视频观看 | 久久99久久99精品免视看婷婷 | 又黄又爽又色无遮挡免费 | 黄色av电影网 | 一级黄色在线免费观看 | 国产精品精品 | 99精品国产免费久久久久久下载 | 国产精品白虎 | 色婷婷啪啪免费在线电影观看 | 91片在线观看 | 中文字幕精品久久 | 亚洲精品97 | 99热在线国产 | 精品福利在线观看 | 久久99精品视频 | 久久国产精品99久久久久久进口 | 亚洲国产精品久久久久婷婷884 | 69国产精品成人在线播放 | 99精品免费在线 | 国产中文字幕一区二区 | 亚洲天堂网在线视频观看 | 国产女教师精品久久av | a电影免费看| 四虎伊人 | 精品美女久久久久久免费 | 国产在线视频导航 | 狠色狠色综合久久 | 99国产精品久久久久老师 | 伊人干综合 | 午夜12点 | 九九日九九操 | 亚洲精品影院在线观看 | 日韩动漫免费观看高清完整版在线观看 | 国产精品欧美久久久久无广告 | 九九免费观看视频 | 麻豆影音先锋 | 日韩免费在线观看视频 | 国产精品麻豆欧美日韩ww | 免费a视频在线观看 | 国产福利精品视频 | 中文字幕一区二区在线播放 | 黄色网址国产 | 欧美激情一区不卡 | 黄色网址中文字幕 | 天天精品视频 | 国产高清av免费在线观看 | 91在线在线观看 | 99久久久久久久久 | 久久在视频 | 五月婷婷视频在线 | 黄色在线观看免费网站 | 亚洲人成在 | 亚洲日本欧美在线 | 亚洲欧美精品在线 | 欧美日韩免费观看一区=区三区 | 成年人免费在线观看 | 欧美久久久久久久久久 | 亚洲视频资源在线 | 手机av电影在线观看 | 国产成人三级在线 | 91在线免费公开视频 | 亚洲春色奇米影视 | www.xxxx欧美| 丝袜精品视频 | 99久热精品 | 亚洲精品大片www | 91av社区| 国产经典三级 | 久久99精品久久久久蜜臀 | 国产成人av电影在线 | 色香蕉网 | 精品一二 | 99精品国产99久久久久久福利 | 五月天婷婷视频 | 西西人体www444| av在观看 | 亚洲精品乱码久久久久久蜜桃欧美 | 黄色免费观看 | 国产又粗又猛又黄又爽视频 | 成人免费网站在线观看 | 狠狠干狠狠色 | 婷婷丁香狠狠爱 | 久久九九久久九九 | 超碰在线98| 美女网站视频免费都是黄 | 91精品国产高清自在线观看 | 中文字幕在线中文 | 国产视频97 | 久久97超碰| 久久理论影院 | 日韩在线大片 | av片子在线观看 | 综合在线亚洲 | 欧美一级免费黄色片 | 在线国产视频一区 | 96亚洲精品久久久蜜桃 | 在线观看91网站 | 国产麻豆精品在线观看 | 久久成人福利 | 日韩精品不卡 | 韩国一区二区三区在线观看 | 亚洲综合国产精品 | 亚洲免费一级 | 九九久久久久久久久激情 | 天堂在线免费视频 | av在线网站大全 | 丁香激情网 | 中文字幕在线视频一区二区三区 | a在线一区| 黄色毛片在线 | 亚洲乱码中文字幕综合 | 99九九热只有国产精品 | 国产91区 | 可以免费观看的av片 | 久久久久久国产精品美女 | 黄色av高清 | 成人免费看片98欧美 | 亚洲精品在线观看免费 | 欧美国产在线看 | 偷拍区另类综合在线 | www.av免费 | 在线观看电影av | 国产精品久久久久av福利动漫 | 九九九免费视频 | 国产精美视频 | 久久精品一区二区三区中文字幕 | 丁香婷婷综合色啪 | www久久| 天堂av官网 | 五月婷网站 | 91大神视频网站 | 精品福利国产 | 亚洲精品综合一区二区 | 天天干天天操天天搞 | 欧美日韩国产亚洲乱码字幕 | 91麻豆精品国产91久久久使用方法 | 四虎在线观看 | 91精品一区二区三区蜜桃 | 正在播放国产91 | 成人中文字幕在线观看 | 免费网站在线观看人 | 最新中文字幕在线资源 | 亚洲精品中文在线 | 婷婷综合成人 | 碰超在线观看 | 国产精品白虎 | 一本一本久久a久久 | 一级免费观看 | 国产日韩欧美综合在线 | 91看片网址 | 欧美成人视 | 婷婷丁香av | 日本性生活免费看 | 国产高清中文字幕 | 久久黄色a级片 | 伊人狠狠干| 中文字幕在线免费看 | 久久久久久久久久久成人 | 日韩大片免费观看 | 黄网站app在线观看免费视频 | 黄色电影在线免费观看 | 日日操夜| 婷婷国产在线 | 久久久久久久免费观看 | 国产一区私人高清影院 | 久久伊人婷婷 | 国产在线欧美在线 | 欧美日性视频 | 麻豆视频在线 | 亚洲精品九九 | 国产福利一区在线观看 | 中文字幕在线播放视频 | av7777777| 首页中文字幕 | 国产拍揄自揄精品视频麻豆 | 国产网站色 | 免费日韩视 |