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

 
 介於最近express 中文文檔比較難找的現狀,特意找了一個,供你們學習思考

Express 4.x API

express 翻譯 api文檔 中文javascript


--css

 
 

express()

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

 
  1. var express = require('express');
  2. var app = express();
 

Methods

 

express.static(root, [options])

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

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

若是你想得到更多關於使用中間件的細節,你能夠查閱Serving static files in Expressvue

 

Application()

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

 
  1. var express = require('express');
  2. var app = express();
  3. app.get('/', function(req, res) {
  4. res.send('hello world!');
  5. });
  6. app.listen(3000);

app對象具備如下的方法:node

它還有一些屬性設置,這些屬性能夠改變程序的行爲。得到更多的信息,能夠查閱Application settingsjquery

 

Properties

 

app.locals

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

 
  1. app.locals.title
  2. // => 'My App'
  3. app.locals.email
  4. // => 'me@myapp.com'

一旦設定,app.locals的各屬性值將貫穿程序的整個生命週期,與其相反的是res.locals,它只在此次請求的生命週期中有效。github

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

 
  1. app.locals.title = 'My App';
  2. app.locals.strftime = require('strftime');
  3. app.locals.email = 'me@myapp.com';
 

app.mountpath

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

一個子程序是一個express的實例,其能夠被用來做爲路由句柄來處理請求。

 
  1. var express = require('express');
  2. var app = express(); // the main app
  3. var admin = express(); // the sub app
  4. admin.get('/', function(req, res) {
  5. console.log(admin.mountpath); // /admin
  6. res.send('Admin Homepage');
  7. });
  8. app.use('/admin', admin); // mount the sub app

它和req對象的baseUrl屬性比較類似,除了req.baseUrl是匹配的URL路徑,而不是匹配的模式。若是一個子程序被掛載在多條路徑模式,app.mountpath就是一個關於掛載路徑模式項的列表,以下面例子所示。

 
  1. var admin = express();
  2. admin.get('/', function(req, res) {
  3. console.log(admin.mountpath); // ['adm*n', '/manager']
  4. res.send('Admin Homepage');
  5. });
  6. var secret = express();
  7. secret.get('/', function(req, res) {
  8. console.log(secret.mountpath); // /secr*t
  9. res.send('Admin secret');
  10. });
  11. admin.use('/secr*t', secret); // load the 'secret' router on '/secr*t', on the 'admin' sub app
  12. 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事件被髮射。父程序對象做爲參數,傳遞給回調方法。

 
  1. var admin = express();
  2. admin.on('mount', function(parent) {
  3. console.log('Admin Mounted');
  4. console.log(parent); // refers to the parent app
  5. });
  6. admin.get('/', function(req, res) {
  7. res.send('Admin Homepage');
  8. });
  9. app.use('/admin', admin);
 

Methods

 

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

app.all方法和標準的app.METHOD()方法類似,除了它匹配全部的HTTP動詞。 
對於給一個特殊前綴映射一個全局的邏輯處理,或者無條件匹配,它是頗有效的。例如,若是你把下面內容放在全部其餘的路由定義的前面,它要求全部從這個點開始的路由須要認證和自動加載一個用戶。記住這些回調並非必定是終點:loadUser能夠在完成了一個任務後,調用next()方法來繼續匹配隨後的路由。

 
  1. app.all('*', requireAuthentication, loadUser);

或者這種相等的形式:

 
  1. app.all('*', requireAuthentication);
  2. app.all('*', loadUser);

另外一個例子是全局的白名單方法。這個例子和前面的很像,然而它只是限制以/api開頭的路徑。

 
  1. app.all('/api/*', requireAuthentication);
 

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

路由HTTP DELETE請求到有特殊回調方法的特殊的路徑。獲取更多的信息,能夠查閱routing guide。 
你能夠提供多個回調函數,它們的行爲和中間件同樣,除了這些回調能夠經過調用next('router')來繞過剩餘的路由回調。你可使用這個機制來爲一個路由設置一些前提條件,若是不能知足當前路由的處理條件,那麼你能夠傳遞控制到隨後的路由。

 
  1. app.delete('/', function(req, res) {
  2. res.send('DELETE request to homepage');
  3. });
 

app.disable(name)

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

 
  1. app.disable('trust proxy');
  2. app.get('trust proxy');
  3. // => false
 

app.disabled(name)

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

 
  1. app.disabled('trust proxy');
  2. // => true
  3. app.enable('trust proxy');
  4. app.disabled('trust proxy');
  5. // => false
 

app.enable(name)

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

 
  1. app.enable('trust proxy');
  2. app.get('trust proxy');
  3. // => true
 

app.enabled(name)

返回true若是布爾類型的設置值name被啓動爲true,此處的nameapp settings table中各屬性的一個。

 
  1. app.enabled('trust proxy');
  2. // => false
  3. app.enable('trust proxy');
  4. app.enabled('trust proxy');
  5. // => true
 

app.engine(ext, callback)

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

 
  1. app.engine('jade', require('jade').__express);

使用下面的方法對於那些沒有提供開箱即用的.__express方法的模板,或者你但願使用不一樣的模板引擎擴展。 
好比,使用EJS模板引擎來渲染.html文件:

 
  1. app.engine('html', require('ejs').renderFile);

在這個例子中,EJS提供了一個.renderFile方法,這個方法知足了Express規定的簽名規則:(path, options, callback),然而記住在內部它只是ejs.__express的一個別名,因此你能夠在不作任何事的狀況下直接使用.ejs擴展。 
一些模板引擎沒有遵循這種規範,consolidate.js庫映射模板引擎如下面的使用方式,因此他們能夠無縫的和Express工做。

 
  1. var engines = require('consolidate');
  2. app.engine('haml', engines.haml);
  3. app.engine('html', engines.hogan);
 

app.get(name)

得到設置名爲name的app設置的值,此處的nameapp settings table中各屬性的一個。 
以下:

 
  1. app.get('title');
  2. // => undefined
  3. app.set('title', 'My Site');
  4. app.get('title');
  5. // => 'My Site'
 

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

路由HTTP GET請求到有特殊回調的特殊路徑。獲取更多的信息,能夠查閱routing guide。 
你能夠提供多個回調函數,它們的行爲和中間件同樣,除了這些回調能夠經過調用next('router')來繞過剩餘的路由回調。你可使用這個機制來爲一個路由設置一些前提條件,若是請求沒能知足當前路由的處理條件,那麼傳遞控制到隨後的路由。

 
  1. app.get('/', function(req, res) {
  2. res.send('GET request to homepage');
  3. });
 

app.listen(port, [hostname], [backlog], [callback])

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

 
  1. var express = require('express');
  2. var app = express();
  3. app.listen(3000);

經過調用express()返回獲得的app其實是一個JavaScript的Function,被設計用來做爲一個回調傳遞給Node HTTP servers來處理請求。這樣,其就能夠很簡便的基於同一份代碼提供http和https版本,因此app沒有從這些繼承(它只是一個簡單的回調)。

 
  1. var express = require('express');
  2. var https = require('https');
  3. var http = require('http');
  4. http.createServer(app).listen(80);
  5. https.createServer(options, app).listen(443);

app.listen()方法是下面所示的一個便利的方法(只針對HTTP協議):

 
  1. app.listen = function() {
  2. var server = http.createServer(this);
  3. return server.listen.apply(server, arguments);
  4. };
 

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

路由一個HTTP請求,METHOD是這個請求的HTTP方法,好比GETPUTPOST等等,注意是小寫的。因此,實際的方法是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.postapp.put()app.delete()做爲一個個單獨的項進行說明。然而,其餘上述列出的方法以徹底相同的方式工做。

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

 
  1. app.all('/secret', function (req, res) {
  2. console.log('Accessing the secret section...');
  3. next(); // pass control to the next handler
  4. });
 

app.param([name], callback)

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

 
  1. app.param('user', function(req, res, next, id) {
  2. User.find(id, function(error, user) {
  3. if (err) {
  4. next(err);
  5. }
  6. else if (user){
  7. req.user = user;
  8. } else {
  9. next(new Error('failed to load user'));
  10. }
  11. });
  12. });

對於Param的回調定義的路由來講,他們是局部的。它們不會被掛載的app或者路由繼承。因此,定義在app上的Param回調只有是在app上的路由具備這個路由參數時才起做用。 
在定義param的路由上,param回調都是第一個被調用的,它們在一個請求-響應循環中都會被調用一次而且只有一次,即便多個路由都匹配,以下面的例子:

 
  1. app.param('id', function(req, res, next, id) {
  2. console.log('CALLED ONLY ONCE');
  3. next();
  4. });
  5. app.get('/user/:id', function(req, res, next) {
  6. console.log('although this matches');
  7. next();
  8. });
  9. app.get('/user/:id', function(req, res) {
  10. console.log('and this mathces too');
  11. res.end();
  12. });

GET /user/42,獲得下面的結果:

 
  1. CALLED ONLY ONCE
  2. although this matches
  3. and this matches too
 
  1. app.param(['id', 'page'], function(req, res, next, value) {
  2. console.log('CALLED ONLY ONCE with', value);
  3. next();
  4. });
  5. app.get('/user/:id/:page', function(req. res, next) {
  6. console.log('although this matches');
  7. next();
  8. });
  9. app.get('/user/:id/:page', function (req, res, next) {
  10. console.log('and this matches too');
  11. res.end();
  12. });

當執行GET /user/42/3,結果以下:

 
  1. CALLED ONLY ONCE with 42
  2. CALLED ONLY ONCE with 3
  3. although this matches
  4. 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()如今接受一個參數名和一個數字。

 
  1. var express = require('express');
  2. var app = express();
  3. app.param(function(param, option){
  4. return function(req, res, next, val) {
  5. if (val == option) {
  6. next();
  7. }
  8. else {
  9. res.sendStatus(403);
  10. }
  11. }
  12. });
  13. app.param('id', 1337);
  14. app.get('/user/:id', function(req, res) {
  15. res.send('Ok');
  16. });
  17. app.listen(3000, function() {
  18. console.log('Ready');
  19. });

在這個例子中,app.param(name, callback)參數簽名保持和原來同樣,可是替換成了一箇中間件,定義了一個自定義的數據類型檢測方法來檢測user id的類型正確性。

 
  1. app.param(function(param, validator) {
  2. return function(req, res, next, val) {
  3. if (validator(val)) {
  4. next();
  5. }
  6. else {
  7. res.sendStatus(403);
  8. }
  9. }
  10. });
  11. app.param('id', function(candidate) {
  12. return !isNaN(parseFloat(candidate)) && isFinite(candidate);
  13. });

在使用正則表達式來,不要使用.。例如,你不能使用/user-.+/來捕獲user-gami,用使用[\\s\\S]或者[\\w\\>W]來代替(正如/user-[\\s\\S]+/)。

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

app.path()

經過這個方法能夠獲得app典型的路徑,其是一個string

 
  1. var app = express()
  2. , blog = express()
  3. , blogAdmin = express();
  4. app.use('/blog', blog);
  5. app.use('/admin', blogAdmin);
  6. console.log(app.path()); // ''
  7. console.log(blog.path()); // '/blog'
  8. console.log(blogAdmin.path()); // '/blog/admin'

若是app掛載很複雜下,那麼這個方法的行爲也會很複雜:一種更好用的方式是使用req.baseUrl來得到這個app的典型路徑。

 

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

路由HTTP POST請求到有特殊回調的特殊路徑。獲取更多的信息,能夠查閱routing guide。 
你能夠提供多個回調函數,它們的行爲和中間件同樣,除了這些回調能夠經過調用next('router')來繞過剩餘的路由回調。你可使用這個機制來爲一個路由設置一些前提條件,若是請求沒能知足當前路由的處理條件,那麼傳遞控制到隨後的路由。

 
  1. app.post('/', function(req, res) {
  2. res.send('POST request to homepage')
  3. });
 

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

路由HTTP PUT請求到有特殊回調的特殊路徑。獲取更多的信息,能夠查閱routing guide。 
你能夠提供多個回調函數,它們的行爲和中間件同樣,除了這些回調能夠經過調用next('router')來繞過剩餘的路由回調。你可使用這個機制來爲一個路由設置一些前提條件,若是請求沒能知足當前路由的處理條件,那麼傳遞控制到隨後的路由。

 
  1. app.put('/', function(req, res) {
  2. res.send('PUT request to homepage');
  3. });
 

app.render(view, [locals], callback)

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

app.render()看成是能夠生成渲染視圖字符串的工具方法。在res.render()內部,就是使用的app.render()來渲染視圖。

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

 
  1. app.render('email', function(err, html) {
  2. // ...
  3. });
  4. app.render('email', {name:'Tobi'}, function(err, html) {
  5. // ...
  6. });
 

app.route(path)

返回一個單例模式的路由的實例,以後你能夠在其上施加各類HTTP動做的中間件。使用app.route()來避免重複路由名字(所以錯字錯誤)--說的意思應該是使用app.router()這個單例方法來避免同一個路徑多個路由實例。

 
  1. var app = express();
  2. app.route('/events')
  3. .all(function(req, res, next) {
  4. // runs for all HTTP verbs first
  5. // think of it as route specific middleware!
  6. })
  7. .get(function(req, res, next) {
  8. res.json(...);
  9. })
  10. .post(function(req, res, next) {
  11. // maybe add a new event...
  12. })
 

app.set(name, value)

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

 
  1. app.set('title', 'My Site');
  2. app.get('title'); // 'My Site'

Application Settings 
若是name是程序設置之一,它將影響到程序的行爲。下邊列出了程序中的設置。

Property Type Value Default
case sensitive routing Boolean 啓用區分大小寫。 不啓用。對/Foo/foo處理是同樣。
env String 環境模型。 process.env.NODE_ENV(NODE_ENV環境變量)或者"development"
etag Varied 設置ETag響應頭。可取的值,能夠查閱etag options table。更多關於HTTP ETag header weak
jsonp callback name String 指定默認JSONP回調的名稱。 ?callback=
json replacer String JSON替代品回調 null
json spaces Number 當設置了這個值後,發送縮進空格美化過的JSON字符串。 Disabled
query parser Varied 設置值爲false來禁用query parser,或者設置simple,extended,也能夠本身實現query string解析函數。simple基於Node原生的query解析,querystring "extend"
strict routing Boolean 啓用嚴格的路由。 不啓用。對/foo/foo/的路由處理是同樣。
subdomain offset Number 用來刪除訪問子域的主機點分部分的個數 2
trust proxy Varied 指示app在一個反向代理的後面,使用x-Forwarded-*來肯定鏈接和客戶端的IP地址。注意:X-Forwarded-*頭部很容易被欺騙,全部檢測客戶端的IP地址是靠不住的。trust proxy默認不啓用。當啓用時,Express嘗試經過前端代理或者一系列代理來獲取已鏈接的客戶端IP地址。req.ips屬性包含了已鏈接客戶端IP地址的一個數組。爲了啓動它,須要設置在下面trust proxy options table中定義的值。trust proxy的設置實現使用了proxy-addr包。若是想得到更多的信息,能夠查閱它的文檔 Disable
views String or Array view所在的目錄或者目錄數組。若是是一個數組,將按在數組中的順序來查找view process.cwd() + '/views'
view cache Boolean 啓用視圖模板編譯緩存。 在生成環境默認開啓。
view engine String 省略時,默認的引擎被擴展使用。  
x-powered-by Boolean 啓用X-Powered-By:ExpressHTTP頭部 true

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

Type Value
Boolean

若是爲true,客戶端的IP地址做爲X-Forwarded-*頭部的最左邊的條目。若是爲false,能夠理解爲app直接與英特網直連,客戶端的IP地址衍生自req.connection.remoteAddressfalse是默認設置。

IP addresses

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

  • loopback - 127.0.0.1/8::1/128
  • linklocal - 169.254.0.0/16fe80::/10
  • uniquelocal - 10.0.0.0/8172.16.0.0/12192.168.0.0/16fc00::/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包。若是你須要得到更多的信息,你能夠查閱它的文檔。

Type Value
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.originalUrlreq.baseUrlreq.path的組合,以下面的例子所示。

  1. app.use('/admin', function(req, res, next) {
  2. // GET 'http://www.example.com/admin/new'
  3. console.log(req.originalUrl); // '/admin/new'
  4. console.log(req.baseUrl); // '/admin'
  5. console.log(req.path);// '/new'
  6. });

在一個路徑上掛載一箇中間件以後,每當請求的路徑的前綴部分匹配了這個路由路徑,那麼這個中間件就會被執行。 
因爲默認的路徑爲/,中間件掛載沒有指定路徑,那麼對於每一個請求,這個中間件都會被執行。

 
  1. // this middleware will be executed for every request to the app.
  2. app.use(function(req, res, next) {
  3. console.log('Time: %d', Date.now());
  4. next();
  5. });

中間件方法是順序處理的,因此中間件包含的順序是很重要的。

 
  1. // this middleware will not allow the request to go beyond it
  2. app.use(function(req, res, next) {
  3. res.send('Hello World');
  4. });
  5. // this middleware will never reach this route
  6. app.use('/', function(req, res) {
  7. res.send('Welcome');
  8. });

路徑能夠是表明路徑的一串字符,一個路徑模式,一個匹配路徑的正則表達式,或者他們的一組集合。

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

Type Example
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(); })

方法能夠是一箇中間件方法,一系列中間件方法,一組中間件方法或者他們的集合。因爲routerapp實現了中間件接口,你能夠像使用其餘任一中間件方法那樣使用它們。

Usage Example
單箇中間件 你能夠局部定義和掛載一箇中間件。
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目錄下的靜態資源:

 
  1. // GET /style.css etc
  2. app.use(express.static(__dirname + '/public'));

/static路徑下掛載中間件來提供靜態資源託管服務,只當請求是以/static爲前綴的時候。

 
  1. // GET /static/style.css etc.
  2. app.use('/static', express.static(express.__dirname + '/public'));

經過在設置靜態資源中間件以後加載日誌中間件來關閉靜態資源請求的日誌。

 
  1. app.use(express.static(__dirname + '/public'));
  2. app.use(logger());

託管靜態資源從不一樣的路徑,但./public路徑比其餘更容易被匹配:

 
  1. app.use(express.static(__dirname + '/public'));
  2. app.use(express.static(__dirname + '/files'));
  3. app.use(express.static(__dirname + '/uploads'));
 

Request

req對象表明了一個HTTP請求,其具備一些屬性來保存請求中的一些數據,好比query stringparametersbodyHTTP headers等等。在本文檔中,按照慣例,這個對象老是簡稱爲req(http響應簡稱爲res),可是它們實際的名字由這個回調方法在那裏使用時的參數決定。 
以下例子:

 
  1. app.get('/user/:id', function(req, res) {
  2. res.send('user' + req.params.id);
  3. });

其實你也能夠這樣寫:

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

Properties

Express 4中,req.files默認在req對象中再也不是可用的。爲了經過req.files對象來得到上傳的文件,你可使用一個multipart-handling(多種處理的工具集)中間件,好比busboymulterformidablemultipratyconnect-multiparty或者pez

 

req.app

這個屬性持有express程序實例的一個引用,其能夠做爲中間件使用。 
若是你按照這個模式,你建立一個模塊導出一箇中間件,這個中間件只在你的主文件中require()它,那麼這個中間件能夠經過req.app來獲取express的實例。 
例如:

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

req.baseUrl

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

 
  1. var greet = express.Router();
  2. greet.get('/jp', function(req, res) {
  3. console.log(req.baseUrl); // greet
  4. res.send('Konichiwa!');
  5. });
  6. app.use('/greet', greet);

即便你使用的路徑模式或者一系列路徑模式來加載路由,baseUrl屬性返回匹配的字符串,而不是路由模式。下面的例子,greet路由被加載在兩個路徑模式上。

 
  1. app.use(['/gre+t', 'hel{2}o'], greet); // load the on router on '/gre+t' and '/hel{2}o'

當一個請求路徑是/greet/jpbaseUrl/greet,當一個請求路徑是/hello/jpreq.baseUrl/hello。 
req.baseUrlapp對象的mountpath屬性類似,除了app.mountpath返回的是路徑匹配模式。

 

req.body

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

 
  1. var app = require('express');
  2. var bodyParser = require('body-parser');
  3. var multer = require('multer');// v1.0.5
  4. var upload = multer(); // for parsing multipart/form-data
  5. app.use(bodyParser.json()); // for parsing application/json
  6. app.use(bodyParser.urlencoded({extended:true})); // for parsing application/x-www-form-urlencoded
  7. app.post('/profile', upload.array(), function(req, res, next) {
  8. console.log(req.body);
  9. res.json(req.body);
  10. });
 

req.cookies

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

 
  1. // Cookie: name=tj
  2. req.cookies.name
  3. // => "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響應頭(徹底不知道什麼鬼)。
 
  1. req.fresh
  2. // => true
 

req.hostname

包含了源自HostHTTP頭部的hostname。 
trust proxy設置項被設置爲啓用值,X-Forwarded-Host頭部被使用來代替Host。這個頭部能夠被客戶端或者代理設置。

 
  1. // Host: "example.com"
  2. req.hostname
  3. // => "example.com"
 

req.ips

trust proxy設置項被設置爲啓用值,這個屬性包含了一組在X-Forwarded-For請求頭中指定的IP地址。否則,其就包含一個空的數組。這個頭部能夠被客戶端或者代理設置。 
例如,若是X-Forwarded-Forclientproxy1proxy2req.ips就是["clinet", "proxy1", "proxy2"],這裏proxy2就是最遠的下游。

 

req.originalUrl

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

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

 
  1. // GET /search?q=something
  2. req.originalUrl
  3. // => "/search?q=something"
 

req.params

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

 
  1. // GET /user/tj
  2. req.params.name
  3. // => "tj"

當你使用正則表達式來定義路由規則,捕獲組的組合通常使用req.params[n],這裏的n是第幾個捕獲租。這個規則被施加在無名通配符匹配,好比/file/*的路由:

 
  1. // GET /file/javascripts/jquery.js
  2. req.params[0]
  3. // => "javascripts/jquery.js"
 

req.path

包含請求URL的部分路徑。

 
  1. // example.com/users?sort=desc
  2. req.path
  3. // => "/users"

當在一箇中間件中被調用,掛載點不包含在req.path中。你能夠查閱app.use()得到跟多的信息。

 

req.protocol

請求的協議,通常爲http,當啓用TLS加密,則爲https。 
trust proxy設置一個啓用的參數,若是存在X-Forwarded-Proto頭部的話,其將被信賴和使用。這個頭部能夠被客戶端或者代理設置。

 
  1. req.ptotocol
  2. // => "http"
 

req.query

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

 
  1. // GET /search?q=tobi+ferret
  2. req.query.q
  3. // => "tobi ferret"
  4. // GET /shoes?order=desc&shoe[color]=blue&shoe[type]=converse
  5. req.query.order
  6. // => "desc"
  7. req.query.shoe.color
  8. // => "blue"
  9. req.query.shoe.type
  10. // => "converse"
 

req.route

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

 
  1. app.get('/user/:id?', function userIdHandler(req, res) {
  2. console.log(req.route);
  3. res.send('GET')
  4. })

前面片斷的輸出爲:

 
  1. { path:"/user/:id?"
  2. stack:
  3. [
  4. { handle:[Function:userIdHandler],
  5. name:"userIdHandler",
  6. params:undefined,
  7. path:undefined,
  8. keys:[],
  9. regexp:/^\/?$/i,
  10. method:'get'
  11. }
  12. ]
  13. methods:{get:true}
  14. }
 

req.secure

一個布爾值,若是創建的是TLS的鏈接,那麼就爲true。等價與:

 
  1. 'https' == req.protocol;
 

req.signedCookies

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

 
  1. // Cookie: user=tobi.CP7AWaXDfAKIRfH49dQzKJx7sKzzSoPq7/AcBBRVwlI3
  2. req.signedCookies.user
  3. // => "tobi"

爲了獲取更多的信息,問題或者關注,能夠參閱cookie-parser

 

req.stale

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

 
  1. req.stale
  2. // => true
 

req.subdomains

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

 
  1. // Host: "tobi.ferrets.example.com"
  2. req.subdomains
  3. // => ["ferrets", "tobi"]
 

req.xhr

一個布爾值,若是X-Requested-With的值爲XMLHttpRequest,那麼其爲true,其指示這個請求是被一個客服端庫發送,好比jQuery

 
  1. req.xhr
  2. // => true
 

Methods

 

req.accepts(types)

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

 
  1. // Accept: text/html
  2. req.accepts('html');
  3. // => "html"
  4. // Accept: text/*, application/json
  5. req.accepts('html');
  6. // => "html"
  7. req.accepts('text/html');
  8. // => "text/html"
  9. req.accepts(['json', 'text']);
  10. // => "json"
  11. req.accepts('application/json');
  12. // => "application/json"
  13. // Accept: text/*, application/json
  14. req.accepts('image/png');
  15. req.accepts('png');
  16. // => undefined
  17. // Accept: text/*;q=.5, application/json
  18. req.accepts(['html', 'json']);
  19. // => "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頭部的域內容(不區分大小寫)。ReferrerReferer的域內容可互換。

 
  1. req.get('Content-type');
  2. // => "text/plain"
  3. req.get('content-type');
  4. // => "text/plain"
  5. req.get('Something')
  6. // => undefined

其是req.header(field)的別名。

 

req.is(type)

若是進來的請求的Content-type頭部域匹配參數type給定的MIME type,那麼其返回true。不然返回false

 
  1. // With Content-Type: text/html; charset=utf-8
  2. req.is('html');
  3. req.is('text/html');
  4. req.is('text/*');
  5. // => true
  6. // When Content-Type is application/json
  7. req.is('json');
  8. req.is('application/json');
  9. req.is('application/*');
  10. // => true
  11. req.is('html');
  12. // => false

獲取更多信息,或者若是你有問題或關注,能夠參閱type-is

 

req.param(naem, [, defaultValue])

過期的。能夠在適合的狀況下,使用req.paramsreq.body或者req.query

返回當前參數name的值。

 
  1. // ?name=tobi
  2. req.param('name')
  3. // => "tobi"
  4. // POST name=tobi
  5. req.param('name')
  6. // => "tobi"
  7. // /user/tobi for /user/:name
  8. req.param('name')
  9. // => "tobi"

按下面給出的順序查找:

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

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

直接經過req.paramsreq.bodyreq.query取得應該更加的清晰-除非你肯定每個對象的輸入。 
Body-parser中間件必須加載,若是你使用req.param()。詳細請看req.body

 

Response

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

 
  1. app.get('/user/:id', function(req, res) {
  2. res.send('user' + req.params.id);
  3. });

這樣寫也是同樣的:

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

Properties

 

res.app

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

 

res.headersSent

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

 
  1. app.get('/', function(req, res) {
  2. console.log(res.headersSent); // false
  3. res.send('OK'); // send以後就發送了頭部
  4. console.log(res.headersSent); // true
  5. });
 

res.locals

一個對象,其包含了響應的可以反應出請求的本地參數和所以只提供給視圖渲染,在請求響應的週期內(若是有的話)--我要翻譯吐了。不然,其和app.locals是同樣的。(不知道翻譯的什麼...) 
這個參數在導出請求級別的信息是頗有效的,這些信息好比請求路徑,已認證的用戶,用戶設置等等。

 
  1. app.use(function(req, res, next) {
  2. res.locals.user = req.user;
  3. res.locals.authenticated = !req.user.anonymous;
  4. next();
  5. });
 

Methods

 

res.append(field [, value])

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

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

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

res.attachment([filename])

設置HTTP響應的Content-Disposition頭內容爲"attachment"。若是提供了filename,那麼將經過res.type()得到擴展名來設置Content-Type,而且設置Content-Disposition內容爲"filename="parameter。

 
  1. res.attachment();
  2. // Content-Disposition: attachment
  3. res.attachment('path/to/logo.png');
  4. // Content-Disposition: attachment; filename="logo.png"
  5. // Content-Type: image/png
 

res.cookie(name, value [,options])

設置namevaluecookievalue參數能夠是一串字符或者是轉化爲json字符串的對象。 
options是一個對象,其能夠有下列的屬性。

屬性 類型 描述
domain String 設置cookie的域名。默認是你本app的域名。
expires Date cookie的過時時間,GMT格式。若是沒有指定或者設置爲0,則產生新的cookie。
httpOnly Boolean 這個cookie只能被web服務器獲取的標示。
maxAge String 是設置過去時間的方便選項,其爲過時時間到當前時間的毫秒值。
path String cookie的路徑。默認值是/
secure Boolean 標示這個cookie只用被HTTPS協議使用。
signed Boolean 指示這個cookie應該是簽名的。

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

使用實例:

 
  1. res.cookie('name', 'tobi', {'domain':'.example.com', 'path':'/admin', 'secure':true});
  2. res.cookie('remenberme', '1', {'expires':new Date(Date.now() + 90000), 'httpOnly':true});

maxAge是一個方便設置過時時間的方便的選項,其以當前時間開始的毫秒數來計算。下面的示例和上面的第二條功效同樣。

 
  1. res.cookie('rememberme', '1', {'masAge':90000}, "httpOnly":true);

你能夠設置傳遞一個對象做爲value的參數。而後其將被序列化爲Json字符串,被bodyParser()中間件解析。

 
  1. res.cookie('cart', {'items':[1, 2, 3]});
  2. res.cookie('cart', {'items':[1, 2, 3]}, {'maxAge':90000});

當咱們使用cookie-parser中間件的時候,這個方法也支持簽名的cookie。簡單地,在設置options時包含signed選項爲true。而後res.cookie()將使用傳遞給cookieParser(secret)的密鑰來簽名這個值。

 
  1. res.cookie('name', 'tobi', {'signed':true});
 

res.clearCookie(name [,options])

根據指定的name清除對應的cookie。更多關於options對象能夠查閱res.cookie()

 
  1. res.cookie('name', 'tobi', {'path':'/admin'});
  2. res.clearCookie('name', {'path':'admin'});
 

res.download(path, [,filename], [,fn])

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

 
  1. res.download('/report-12345.pdf');
  2. res.download('/report-12345.pdf', 'report.pdf');
  3. res.download('report-12345.pdf', 'report.pdf', function(err) {
  4. // Handle error, but keep in mind the response may be partially-sent
  5. // so check res.headersSent
  6. if (err) {
  7. } else {
  8. // decrement a download credit, etc.
  9. }
  10. });
 

res.end([data] [, encoding])

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

 
  1. res.end();
  2. 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")。

 
  1. res.format({
  2. 'text/plain':function() {
  3. res.send('hey')'
  4. },
  5. 'text/html':function() {
  6. res.send('<p>hey</p>');
  7. },
  8. 'application/json':function() {
  9. res.send({message:'hey'});
  10. },
  11. 'default':function() {
  12. res.status(406).send('Not Acceptable');
  13. }
  14. })

除了規範化的MIME類型以外,你也可使用拓展名來映射這些類型來避免冗長的實現:

 
  1. res.format({
  2. text:function() {
  3. res.send('hey');
  4. },
  5. html:function() {
  6. res.send('<p>hey</p>');
  7. },
  8. json:function() {
  9. res.send({message:'hey'});
  10. }
  11. })
 

res.get(field)

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

 
  1. res.get('Content-Type');
  2. // => "text/plain"
 

res.json([body])

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

 
  1. res.json(null);
  2. res.json({user:'tobi'});
  3. res.status(500).json({error:'message'});
 

res.jsonp([body])

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

 
  1. res.jsonp(null)
  2. // => null
  3. res.jsonp({user:'tobi'})
  4. // => {"user" : "tobi"}
  5. res.status(500).jsonp({error:'message'})
  6. // => {"error" : "message"}

默認狀況下,jsonp的回調方法簡單寫做callback。能夠經過jsonp callback name設置來重寫它。 
下面是一些例子使用JSONP響應,使用相同的代碼:

 
  1. // ?callback=foo
  2. res.jsonp({user:'tobo'})
  3. // => foo({"user":"tobi"})
  4. app.set('jsonp callback name', 'cb')
  5. // ?cb=foo
  6. res.status(500).jsonp({error:'message'})
  7. // => foo({"error":"message"})
 

鏈接這些linkslinks是以傳入參數的屬性形式提供,鏈接以後的內容用來填充響應的Link HTTP頭部。

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

效果:

 
  1. Link:<http://api.example.com/users?page=2>;rel="next",
  2. <http://api.example.com/users?page=5>;rel="last"
 

res.location(path)

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

 
  1. res.location('/foo/bar');
  2. res.location('http://example.com');
  3. 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"。

 
  1. res.redirect('/foo/bar');
  2. res.redirect('http://example.com');
  3. res.redirect(301, 'http://example.com');
  4. res.redirect('../login');

重定向也能夠是完整的URL,來重定向到不一樣的站點。

 
  1. res.redirect('http://google.com');

重定向也能夠相對於主機的根路徑。好比,若是程序的路徑爲http://example.com/admin/post/new,那麼下面將重定向到http://example.com/admim:

 
  1. res.redirect('/admin');

重定向也能夠相對於當前的URL。好比,來之於http://example.com/blog/admin/(注意結尾的/),下面將重定向到http://example.com/blog/admin/post/new

 
  1. 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

 
  1. res.redirect('..');

back將重定向請求到referer,當沒有referer的時候,默認爲/

 
  1. res.redirect('back');
 

res.render(view [, locals] [, callback])

渲染一個視圖,而後將渲染獲得的HTML文檔發送給客戶端。可選的參數爲:

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

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

 
  1. // send the rendered view to the client
  2. res.render('index');
  3. // if a callback is specified, the render HTML string has to be sent explicitly
  4. res.render('index', function(err, html) {
  5. res.send(html);
  6. });
  7. // pass a local variable to the view
  8. res.render('user', {name:'Tobi'}, function(err, html) {
  9. // ...
  10. });
 

res.send([body])

發送HTTP響應。 
body參數能夠是一個Buffer對象,一個字符串,一個對象,或者一個數組。好比:

 
  1. res.send(new Buffer('whoop'));
  2. res.send({some:'json'});
  3. res.send('<p>some html</p>');
  4. res.status(404).send('Sorry, we cannot find that!');
  5. res.status(500).send({ error: 'something blew up' });

對於通常的非流請求,這個方法能夠執行許多有用的的任務:好比,它自動給Content-LengthHTTP響應頭賦值(除非先前定義),也支持自動的HEAD和HTTP緩存更新。 
當參數是一個Buffer對象,這個方法設置Content-Type響應頭爲application/octet-stream,除非事先提供,以下所示:

 
  1. res.set('Content-Type', 'text/html');
  2. res.send(new Buffer('<p>some html</p>'));

當參數是一個字符串,這個方法設置Content-Type響應頭爲text/html

 
  1. res.send('<p>some html</p>');

當參數是一個對象或者數組,Express使用JSON格式來表示:

 
  1. res.send({user:'tobi'});
  2. 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-Controlmax-age屬性,格式爲毫秒數,或者是ms format的一串字符串 0  
root 相對文件名的根目錄    
lastModified 設置Last-Modified頭部爲此文件在系統中的最後一次修改時間。設置false來禁用它 Enable 4.9.0+
headers 一個對象,包含了文件所在的sever的HTTP頭部。(不知道怎麼翻譯了)    
dotfiles 是否支持點開頭文件名的選項。可選的值"allow","deny","ignore" "ignore"  

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

 
  1. app.get('/file/:name', function(req, res, next) {
  2. var options = {
  3. root:__dirname + '/public',
  4. dotfile:'deny',
  5. headers:{
  6. 'x-timestamp':Date.now(),
  7. 'x-sent':true
  8. }
  9. };
  10. var fileName = req.params.name;
  11. res.sendFile(fileName, options, function(err) {
  12. if (err) {
  13. console.log(err);
  14. res.status(err.status).end();
  15. }
  16. else {
  17. console.log('sent', fileName);
  18. }
  19. });
  20. });

res.sendFile提供了文件服務的細粒度支持,以下例子說明:

 
  1. app.get('/user/:uid/photos/:file', function(req, res) {
  2. var uid = req.params.uid
  3. , file = req.params.file;
  4. req.user.mayViewFilesFrom(uid, function(yes) {
  5. if (yes) {
  6. res.sendFile('/upload/' + uid + '/' + file);
  7. }
  8. else {
  9. res.status(403).send('Sorry! you cant see that.');
  10. }
  11. });
  12. })

獲取更多信息,或者你有問題或者關注,能夠查閱send

 

res.sendStatus(statusCode)

設置響應對象的HTTP status codestatusCode而且發送statusCode的相應的字符串形式做爲響應的Body。

 
  1. res.sendStatus(200); // equivalent to res.status(200).send('OK');
  2. res.sendStatus(403); // equivalent to res.status(403).send('Forbidden');
  3. res.sendStatus(404); // equivalent to res.status(404).send('Not Found');
  4. res.sendStatus(500); // equivalent to res.status(500).send('Internal Server Error')

若是一個不支持的狀態被指定,這個HTTP status依然被設置爲statusCode而且用這個code的字符串做爲Body。

 
  1. res.sendStatus(2000); // equivalent to res.status(2000).send('2000');

More about HTTP Status Codes

 

res.set(field [, value])

設置響應對象的HTTP頭部fieldvalue。爲了一次設置多個值,那麼能夠傳遞一個對象爲參數。

 
  1. res.set('Content-Type', 'text/plain');
  2. res.set({
  3. 'Content-Type':'text/plain',
  4. 'Content-Length':'123',
  5. 'ETag':'123456'
  6. })

其和res.header(field [,value])效果一致。

 

res.status(code)

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

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

res.type(type)

設置Content-TypeHTTP頭部爲MIME type,若是這個指定的type可以被mime.lookup肯定。若是type包含/字符,那麼設置Content-Typetype(我已經暈了)。

 
  1. res.type('.html'); // => 'text/html'
  2. res.type('html'); // => 'text/html'
  3. res.type('json'); // => 'application/json'
  4. res.type('application/json'); // => 'application/json'
  5. res.type('png'); // => image/png:
 

res.vary(field)

設置Vary響應頭爲field,若是已經不在那裏。(不懂什麼意思)

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

Router

一個router對象是一個單獨的實例關於中間件和路由。你能夠認爲其是一個"mini-application"(迷你程序),其具備操做中間件和路由方法的能力。每一個Express程序有一個內建的app路由。 
路由自身表現爲一箇中間件,因此你可使用它做爲app.use()方法的一個參數或者做爲另外一個路由的use()的參數。 
頂層的express對象有一個Router()方法,你可使用Router()來建立一個新的router對象。

 

Router([options])

以下,能夠建立一個路由:

 
  1. var router = express.Router([options]);

options參數能夠指定路由的行爲,其有下列選擇:

屬性 描述 默認值 可用性
caseSensitive 是否區分大小寫 默認不啓用。對待/Foo/foo同樣。  
mergeParams 保存父路由的res.params。若是父路由參數和子路由參數衝突,子路由參數優先。 false 4.5.0+
strict 使能嚴格路由。 默認不啓用,/foo/foo/被路由同樣對待處理  

你能夠將router看成一個程序,能夠在其上添加中間件和HTTP路由方法(例如getputpost等等)。

 
  1. // invoked for any requests passed to this router
  2. router.use(function(req, res, next) {
  3. // .. some logic here .. like any other middleware
  4. next();
  5. });
  6. // will handle any request that ends in /events
  7. // depends on where the router is "use()'d"
  8. router.get('/events', function(req, res, next) {
  9. // ..
  10. });

你能夠在一個特別的根URL上掛載一個路由,這樣你就以將你的各個路由放到不一樣的文件中或者甚至是mini的程序。

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

Methods

 

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

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

 
  1. router.all('*', requireAuthentication, loadUser);

相等的形式:

 
  1. router.all('*', requireAuthentication)
  2. router.all('*', loadUser);

這是一個白名單全局功能的例子。這個例子很像前面的,不過其僅僅做用於以/api開頭的路徑:

 
  1. router.all('/api/*', requireAuthentication);
 

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

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

 
  1. router.get('/', function(req, res) {
  2. res.send('Hello World');
  3. });

若是你對匹配的path有特殊的限制,你可使用正則表達式,例如,下面的能夠匹配"GET /commits/71dbb9c"和"GET /commits/71bb92..4c084f9"。

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

router.param(name, callback)

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

不像app.param()router.param()不接受一個數組做爲路由參數。

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

 
  1. router.param('user', function(req, res, next, id) {
  2. User.find(id, function(error, user) {
  3. if (err) {
  4. next(err);
  5. }
  6. else if (user){
  7. req.user = user;
  8. } else {
  9. next(new Error('failed to load user'));
  10. }
  11. });
  12. });

對於Param的回調定義的路由來講,他們是局部的。它們不會被掛載的app或者路由繼承。因此,定義在router上的param回調只有是在router上的路由具備這個路由參數時才起做用。 
在定義param的路由上,param回調都是第一個被調用的,它們在一個請求-響應循環中都會被調用一次而且只有一次,即便多個路由都匹配,以下面的例子:

 
  1. router.param('id', function(req, res, next, id) {
  2. console.log('CALLED ONLY ONCE');
  3. next();
  4. });
  5. router.get('/user/:id', function(req, res, next) {
  6. console.log('although this matches');
  7. next();
  8. });
  9. router.get('/user/:id', function(req, res) {
  10. console.log('and this mathces too');
  11. res.end();
  12. });

GET /user/42,獲得下面的結果:

 
  1. CALLED ONLY ONCE
  2. although this matches
  3. 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()如今接受一個參數名和一個數字。

 
  1. var express = require('express');
  2. var app = express();
  3. var router = express.Router();
  4. router.param(function(param, option){
  5. return function(req, res, next, val) {
  6. if (val == option) {
  7. next();
  8. }
  9. else {
  10. res.sendStatus(403);
  11. }
  12. }
  13. });
  14. router.param('id', 1337);
  15. router.get('/user/:id', function(req, res) {
  16. res.send('Ok');
  17. });
  18. app.use(router);
  19. app.listen(3000, function() {
  20. console.log('Ready');
  21. });

在這個例子中,router.param(name. callback)參數簽名保持和原來同樣,可是替換成了一箇中間件,定義了一個自定義的數據類型檢測方法來檢測user id的類型正確性。

 
  1. router.param(function(param, validator) {
  2. return function(req, res, next, val) {
  3. if (validator(val)) {
  4. next();
  5. }
  6. else {
  7. res.sendStatus(403);
  8. }
  9. }
  10. });
  11. router.param('id', function(candidate) {
  12. return !isNaN(parseFloat(candidate)) && isFinite(candidate);
  13. });
 

router.route(path)

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

 
  1. var router = express.Router();
  2. router.param('user_id', function(req, res, next, id) {
  3. // sample user, would actually fetch from DB, etc...
  4. req.user = {
  5. id:id,
  6. name:"TJ"
  7. };
  8. next();
  9. });
  10. router.route('/users/:user_id')
  11. .all(function(req, res, next) {
  12. // runs for all HTTP verbs first
  13. // think of it as route specific middleware!
  14. next();
  15. })
  16. .get(function(req, res, next) {
  17. res.json(req.user);
  18. })
  19. .put(function(req, res, next) {
  20. // just an example of maybe updating the user
  21. req.user.name = req.params.name;
  22. // save user ... etc
  23. res.json(req.user);
  24. })
  25. .post(function(req, res, next) {
  26. next(new Error('not implemented'));
  27. })
  28. .delete(function(req, res, next) {
  29. next(new Error('not implemented'));
  30. })

這種方法重複使用單個/usrs/:user_id路徑來添加了各類的HTTP方法。

 

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

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

 
  1. var express = require('express');
  2. var app = express();
  3. var router = express.Router();
  4. // simple logger for this router`s requests
  5. // all requests to this router will first hit this middleware
  6. router.use(function(req, res, next) {
  7. console.log('%s %s %s', req.method, req.url, req.path);
  8. next();
  9. })
  10. // this will only be invoked if the path starts with /bar form the mount ponit
  11. router.use('/bar', function(req, res, next) {
  12. // ... maybe some additional /bar logging ...
  13. next();
  14. })
  15. // always be invoked
  16. router.use(function(req, res, next) {
  17. res.send('hello world');
  18. })
  19. app.use('/foo', router);
  20. app.listen(3000);

對於中間件function,掛載的路徑是被剝離的和不可見的。關於這個特性主要的影響是對於不一樣的路徑,掛載相同的中間件可能對代碼不作改動,儘管其前綴已經改變。 
你使用router.use()定義中間件的順序很重要。中間們是按序被調用的,因此順序決定了中間件的優先級。例如,一般日誌是你將使用的第一個中間件,以便每個請求都被記錄。

 
  1. var logger = require('morgan');
  2. router.use(logger());
  3. router.use(express.static(__dirname + '/public'));
  4. router.use(function(req, res) {
  5. res.send('Hello');
  6. });

如今爲了支持你不但願記錄靜態文件請求,但爲了繼續記錄那些定義在logger()以後的路由和中間件。你能夠簡單的將static()移動到前面來解決:

 
  1. router.use(express.static(__dirname + '/public'));
  2. router.use(logger());
  3. router.use(function(req, res){
  4. res.send('Hello');
  5. });

另一個確鑿的例子是從不一樣的路徑託管靜態文件,你能夠將./public放到前面來得到更高的優先級:

 
  1. app.use(express.static(__dirname + '/public'));
  2. app.use(express.static(__dirname + '/files'));
  3. app.use(express.static(__dirname + '/uploads'));

router.use()方法也支持命名參數,以便你的掛載點對於其餘的路由而言,可使用命名參數來進行預加載,這樣作是頗有益的。

相關文章
相關標籤/搜索