?
本文檔使用 php中文網(wǎng)手冊 發(fā)布
創(chuàng)建一個Express應用程序。該express()
函數(shù)是express
模塊導出的頂級函數(shù)。
var express = require('express');var app = express();
該中間件在Express v4.16.0及之后版本中提供。
這是Express中內置的中間件功能。它使用JSON有效負載分析傳入請求,并基于body-parser。
返回僅分析JSON并僅查看Content-Type
標題與type
選項匹配的請求的中間件。該解析器接受身體的任何Unicode編碼并支持自動膨脹gzip
和deflate
編碼。
body
包含解析數(shù)據(jù)的新對象request
在中間件(ie req.body
)之后被填充到對象上,或者{}
如果沒有要解析的主體,Content-Type
則不匹配或發(fā)生錯誤,則會填充空對象()。
下表介紹了可選options
對象的屬性。
屬性 | 描述 | 類型 | 默認 |
---|---|---|---|
inflate | 啟用或禁用處理放氣(壓縮)的物體;當禁用時,放氣的物體被拒絕。 | Boolean | true |
limit | 控制最大請求主體大小。如果這是一個數(shù)字,那么該值指定字節(jié)數(shù);如果它是一個字符串,則將該值傳遞給字節(jié)庫以供解析。 | Mixed | “100kb” |
reviver | 作為第二個參數(shù),reviver選項直接傳遞給JSON.parse。您可以在關于JSON.parse的MDN文檔中找到關于此參數(shù)的更多信息。 | Function | null |
strict | 啟用或禁用只接受數(shù)組和對象; 禁用時將接受JSON.parse接受的任何內容。 | Boolean | true |
type | 這用于確定中間件將解析的媒體類型。該選項可以是字符串,字符串數(shù)組或函數(shù)。如果不是函數(shù),則type選項直接傳遞到類型庫,這可以是擴展名(如json),MIME類型(如application / json)或帶有通配符的MIME類型(如* / *或* / json)。如果一個函數(shù),類型選項被稱為fn(req),并且如果它返回一個真值,則請求被解析。 | Mixed | "application/json" |
verify | 如果提供此選項,則稱為verify(req,res,buf,encoding),其中buf是原始請求主體的緩沖區(qū),編碼是請求的編碼。解析可以通過拋出錯誤來中止。 | Function | undefined |
這是Express中內置的中間件功能。它提供靜態(tài)文件并基于服務靜態(tài)。
注:為獲得最佳結果,請使用反向代理緩存來提高服務靜態(tài)資產(chǎn)的性能。
root
參數(shù)指定要從中為靜態(tài)資產(chǎn)提供服務的根目錄。該功能通過req.url
與提供的root
目錄結合來確定要提供的文件。當找不到文件時,它不是發(fā)送404響應,而是調用next()
移動到下一個中間件,允許堆疊和回退。
下表介紹了該options
對象的屬性。另見下面的例子。
Property | Description | Type | Default |
---|---|---|---|
dotfiles | 確定如何處理點文件(以“?!遍_頭的文件或目錄)。請參閱下面的dotfiles。 | String | “ignore” |
etag | 啟用或禁用etag生成注意:express.static總是發(fā)送弱ETags。 | Boolean | true |
extensions | 設置文件擴展名回退:如果找不到文件,請搜索具有指定擴展名的文件并提供找到的第一個文件。例如:'html','htm'。 | Mixed | false |
fallthrough | 讓客戶端錯誤作為未處理的請求發(fā)生,否則轉發(fā)客戶端錯誤。請參閱下面的下文。 | Boolean | true |
immutable | 在Cache-Control響應頭中啟用或禁用不可變指令。如果啟用,還應指定maxAge選項以啟用緩存。不可變的指令將阻止受支持的客戶端在maxAge選項生命期間發(fā)出條件請求,以檢查文件是否已更改。 | Boolean | false |
index | 發(fā)送指定的目錄索引文件。設置為false以禁用目錄索引。 | Mixed | “index.html” |
lastModified | 將Last-Modified標題設置為操作系統(tǒng)上文件的最后修改日期。 | Boolean | true |
maxAge | 以毫秒為單位設置Cache-Control標頭的max-age屬性或以ms格式設置字符串。 | Number | 0 |
redirect | 當路徑名稱是目錄時,重定向到尾隨“/”。 | Boolean | true |
setHeaders | 用于設置HTTP頭文件的功能。請參閱下面的setHeaders。 | Function |
有關更多信息,請參閱在Express中提供靜態(tài)文件,并使用中間件 - 內置中間件。
此選項的可能值為:
“allow” - 沒有針對dotfiles的特殊處理。
“deny” - 拒絕一個點文件的請求,回應403
,然后調用next()
。
“ignore” - 像dotfile不存在一樣,使用404
,然后調用next()
。
注意:使用默認值,它不會忽略以點開頭的目錄中的文件。
如果選擇此選項true
,客戶端錯誤(例如錯誤的請求或對不存在的文件的請求)將導致此中間件僅調用next()
以調用堆棧中的下一個中間件。如果為false,則會調用這些錯誤(即使是404)next(err)
。
設置此選項為true
,以便您可以將多個物理目錄映射到相同的Web地址或路徑以填充不存在的文件。
如果您已經(jīng)將該中間件安裝在嚴格意義上為單個文件系統(tǒng)目錄的路徑中,則可以使用false
路徑,從而可以短接404s以減少壓力。這個中間件也會回復所有的方法。
對于此選項,指定一個函數(shù)來設置自定義響應標頭。對標題的更改必須同步進行。
該函數(shù)的簽名是:
fn(res, path, stat)
參數(shù):
res
,響應對象。
path
,正在發(fā)送的文件路徑。
stat
,stat
正在發(fā)送的文件的對象。
下面是一個使用express.static
中間件功能和精心設計的選項對象的例子:
var options = { dotfiles: 'ignore', etag: false, extensions: ['htm', 'html'], index: false, maxAge: '1d', redirect: false, setHeaders: function (res, path, stat) { res.set('x-timestamp', Date.now()) }} app.use(express.static('public', options))
創(chuàng)建一個新的路由器對象。
var router = express.Router([options]);
可選options
參數(shù)指定路由器的行為。
屬性 | 描述 | 默認 | 可用性 |
---|---|---|---|
caseSensitive | 啟用區(qū)分大小寫。 | 默認情況下禁用,將“/ Foo”和“/ foo”視為相同。 | |
mergeParams | 保留父路由器的req.params值。如果父和子有相互沖突的參數(shù)名稱,則該子的值優(yōu)先。 | false | 4.5.0+ |
strict | 啟用嚴格的路由。 | 默認情況下,“/ foo”和“/ foo /”被路由器視為相同。 |
您可以添加中間件和HTTP方法路由(如get
,put
,post
,等),以router
就像一個應用程序。
有關更多信息,請參閱路由器。
該中間件在Express v4.16.0及之后版本中提供。
這是Express中內置的中間件功能。它使用urlencoded有效負載分析傳入請求,并基于body-parser。
返回僅分析urlencoded主體的中間件,并僅查看Content-Type
標題與type
選項匹配的請求。該解析器只接受身體的UTF-8編碼,并支持自動膨脹gzip
和deflate
編碼。
body
包含解析數(shù)據(jù)的新對象request
在中間件(ie req.body
)之后被填充到對象上,或者{}
如果沒有要解析的主體,Content-Type
則不匹配或發(fā)生錯誤,則會填充空對象()。該對象將包含鍵-值對,其中該值可以是一個字符串或陣列(時extended
是false
),或任何類型的(當extended
是true
)。
下表介紹了可選options
對象的屬性。
屬性 | 描述 | 類型 | 默認 |
---|---|---|---|
extended | 此選項允許選擇使用查詢字符串庫(如果為false)或qs庫(如果為true)解析URL編碼數(shù)據(jù)?!皵U展”語法允許將豐富的對象和數(shù)組編碼為URL編碼格式,從而允許使用URL編碼的類似JSON的體驗。有關更多信息,請參閱qs資料庫。 | Boolean | true |
inflate | 啟用或禁用處理放氣(壓縮)的物體; 當禁用時,放氣的身體被拒絕。 | Boolean | true |
limit | 控制最大請求主體大小。如果這是一個數(shù)字,那么該值指定字節(jié)數(shù); 如果它是一個字符串,則將該值傳遞給字節(jié)庫以供解析。 | Mixed | “100kb” |
parameterLimit | 該選項控制URL編碼數(shù)據(jù)中允許的最大參數(shù)數(shù)量。如果請求包含的參數(shù)多于此值,則會引發(fā)錯誤。 | Number | 1000 |
type | 這用于確定中間件將解析的媒體類型。該選項可以是字符串,字符串數(shù)組或函數(shù)。如果不是函數(shù),則type選項將直接傳遞到type-is庫,這可以是擴展名(如urlencoded),MIME類型(如application / x-www-form-urlencoded)或帶MIME類型的MIME類型通配符(如* / x-www-form-urlencoded)。如果一個函數(shù),類型選項被稱為fn(req),并且如果它返回一個真值,則請求被解析。 | Mixed | "application/x-www-form-urlencoded" |
verify | 如果提供此選項,則稱為verify(req,res,buf,encoding),其中buf是原始請求主體的緩沖區(qū),編碼是請求的編碼。解析可以通過拋出錯誤來中止。 | Function | undefined |
該app
對象通常表示Express應用程序。通過調用express()
Express模塊導出的頂級函數(shù)來創(chuàng)建它:
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。
呈現(xiàn)HTML視圖;請參閱app.render。
注冊模板引擎;請參閱app.engine。
它還具有影響應用程序行為方式的設置(屬性); 有關更多信息,請參閱應用程序設置。
Express應用程序對象可以根據(jù)請求對象和響應對象被稱為對應的req.app
,和res.app
。
app.locals
對象的屬性是應用程序中的局部變量。
app.locals.title// => 'My App' app.locals.email// => 'me@myapp.com'
一旦設置,app.locals
屬性的值將在應用程序的整個生命周期中持續(xù)存在,而res.locals屬性只對請求的生命周期有效。
您可以訪問應用程序中呈現(xiàn)的模板中的局部變量。這對于為模板提供幫助函數(shù)以及應用程序級數(shù)據(jù)很有用。局部變量在中間件中可用req.app.locals
(請參閱req.app)
app.locals.title = 'My App'; app.locals.strftime = require('strftime'); app.locals.email = 'me@myapp.com';
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
mount
事件是在子應用,當它被安裝在一個父應用程序。父應用程序被傳遞給回調函數(shù)。
注意
子應用程序將:
不繼承具有默認值的設置的值。您必須在子應用程序中設置值。
繼承沒有默認值的設置值。
有關詳情,請參閱應用程序設置
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);
此方法與標準的app.METHOD()方法類似,只不過它匹配所有HTTP動詞。
參數(shù) | 描述 | 默認 |
---|---|---|
path | 中間件功能被調用的路徑; 可以是以下任何一種:表示路徑的字符串。路徑模式。一個正則表達式模式來匹配路徑。上述任何組合的數(shù)組。有關示例,請參閱路徑示例。 | '/' (root path) |
callback | 回調函數(shù); 可以是:中間件功能。一系列中間件功能(用逗號分隔)。一系列中間件功能。以上所有組合。您可以提供多個回調函數(shù),其行為就像中間件一樣,只不過這些回調可以調用next('route')來繞過剩余的路由回調。您可以使用此機制在路線上施加先決條件,并在沒有理由繼續(xù)使用當前路線時將控制權交給后續(xù)路線。由于路由器和應用程序實現(xiàn)了中間件接口,因此您可以像使用其他中間件功能一樣使用它們。有關示例,請參閱中間件回調函數(shù)示例。 | None |
表示路徑的字符串。
路徑模式。
一個正則表達式模式來匹配路徑。
上述任何組合的數(shù)組。
有關示例,請參閱路徑示例。'/'(根路徑)callback
回調函數(shù);可以是:
中間件功能。
一系列中間件功能(用逗號分隔)。
一系列中間件功能。
以上所有組合。
您可以提供多個回調函數(shù),其行為與中間件類似,只是這些回調可以調用next('route')
繞過剩余的路由回調。您可以使用此機制在路線上施加先決條件,并在沒有理由繼續(xù)使用當前路線時將控制權交給后續(xù)路線。
由于路由器和應用程序實現(xiàn)了中間件接口,因此您可以像使用其他中間件功能一樣使用它們。
有關示例,請參閱中間件回調函數(shù)示例。
無
以下回調針對/secret
使用GET,POST,PUT,DELETE或任何其他HTTP請求方法的請求執(zhí)行:
app.all('/secret', function (req, res, next) { console.log('Accessing the secret section ...') next() // pass control to the next handler});
app.all()
方法對于為特定路徑前綴或任意匹配映射“全局”邏輯非常有用。例如,如果將以下內容放在所有其他路由定義的頂部,則要求所有來自該點的路由都要求進行身份驗證,并自動加載用戶。請記住,這些回調不必作為終點:loadUser
可以執(zhí)行任務,然后調用next()
繼續(xù)匹配后續(xù)路由。
app.all('*', requireAuthentication, loadUser);
或者相當于:
app.all('*', requireAuthentication);app.all('*', loadUser);
另一個例子是白名單“global”功能。這個例子與上面的例子類似,但它僅限制以“/ api”開頭的路徑:
app.all('/api/*', requireAuthentication);
使用指定的回調函數(shù)將HTTP DELETE請求路由到指定的路徑。有關更多信息,請參閱路由指南。
參數(shù) | 描述 | 默認 |
---|---|---|
path | 中間件功能被調用的路徑;可以是以下任何一種:表示路徑的字符串。路徑模式。一個正則表達式模式來匹配路徑。上述任何組合的數(shù)組。有關示例,請參閱路徑示例。 | '/' (root path) |
callback | 回調函數(shù);可以是:中間件功能、一系列中間件功能(用逗號分隔)、一系列中間件功能、以上所有組合。您可以提供多個回調函數(shù),其行為就像中間件一樣,只不過這些回調可以調用next('route')來繞過剩余的路由回調。您可以使用此機制在路線上施加先決條件,并在沒有理由繼續(xù)使用當前路線時將控制權交給后續(xù)路線。由于路由器和應用程序實現(xiàn)了中間件接口,因此您可以像使用其他中間件功能一樣使用它們。有關示例,請參閱中間件回調函數(shù)示例。 | None |
表示路徑的字符串。
路徑模式。
一個正則表達式模式來匹配路徑。
上述任何組合的數(shù)組。
有關示例,請參閱路徑示例。'/'(根路徑)callback
回調函數(shù); 可以是:
中間件功能。
一系列中間件功能(用逗號分隔)。
一系列中間件功能。
以上所有組合。
您可以提供多個回調函數(shù),其行為與中間件類似,只是這些回調可以調用next('route')
繞過剩余的路由回調。您可以使用此機制在路線上施加先決條件,并在沒有理由繼續(xù)使用當前路線時將控制權交給后續(xù)路線。
由于路由器和應用程序實現(xiàn)了中間件接口,因此您可以像使用其他中間件功能一樣使用它們。
有關示例,請參閱中間件回調函數(shù)示例。
無
app.delete('/', function (req, res) { res.send('DELETE request to homepage');});
將布爾值設置name
為false
,其中name
是應用程序設置表中的其中一個屬性。調用app.set('foo', false)
作為布爾屬性與調用app.disable('foo')
相同。
例如:
app.disable('trust proxy'); app.get('trust proxy');// => false
如果布爾設置name
被禁用(false
),返回true。
其中name
是應用程序設置表中的一個屬性。
app.disabled('trust proxy');// => true app.enable('trust proxy'); app.disabled('trust proxy');// => false
將布爾值設置name
為true
,其中name
是應用程序設置表中的其中一個屬性。調用app.set('foo', true)
布爾屬性與調用app.enable('foo')
相同。
app.enable('trust proxy'); app.get('trust proxy');// => true
如果name
啟用了設置(true
),返回true
,其中name
是應用程序設置表中的其中一個屬性。
app.enabled('trust proxy');// => false app.enable('trust proxy'); app.enabled('trust proxy');// => true
將給定的模板引擎注冊callback
為ext
。
默認情況下,Express會根據(jù)文件擴展名來require()
引擎。例如,如果您嘗試呈現(xiàn)“foo.pug”文件,則Express會在內部調用以下內容,并在隨后的調用中緩存require()
以提高性能。
app.engine('pug', require('pug').__express);
對于不提供.__express
開箱即用的引擎,或者如果您希望將不同的擴展名映射到模板引擎,請使用此方法。
例如,要將EJS模板引擎映射到“.html”文件:
app.engine('html', require('ejs').renderFile);
在這種情況下,EJS提供了一個具有Express期望的相同簽名(path, options, callback)
的.renderFile()
方法,但請注意,它在ejs.__express
內部將此方法進行了別名,因此如果使用“.ejs”擴展名,則不需要執(zhí)行任何操作。
Some template engines do not follow this convention. The consolidate.js library maps Node template engines to follow this convention, so they work seamlessly with Express.
var engines = require('consolidate'); app.engine('haml', engines.haml); app.engine('html', engines.hogan);
返回name
應用設置的值,其中name
是應用設置表中的一個字符串。例如:
app.get('title');// => undefined app.set('title', 'My Site'); app.get('title');// => "My Site"
使用指定的回調函數(shù)將HTTP GET請求路由到指定的路徑。
參數(shù) | 描述 | 默認 |
---|---|---|
path | 中間件功能被調用的路徑;可以是以下任何一種:表示路徑的字符串、路徑模式。一個正則表達式模式來匹配路徑。上述任何組合的數(shù)組。有關示例,請參閱路徑示例。 | '/' (root path) |
callback | 回調函數(shù);可以是:中間件功能。一系列中間件功能(用逗號分隔)。一系列中間件功能。以上所有組合。您可以提供多個回調函數(shù),其行為就像中間件一樣,只不過這些回調可以調用next('route')來繞過剩余的路由回調。您可以使用此機制在路線上施加先決條件,并在沒有理由繼續(xù)使用當前路線時將控制權交給后續(xù)路線。由于路由器和應用程序實現(xiàn)了中間件接口,因此您可以像使用其他中間件功能一樣使用它們。有關示例,請參閱中間件回調函數(shù)示例。 | None |
表示路徑的字符串。
路徑模式。
一個正則表達式模式來匹配路徑。
上述任何組合的數(shù)組。
For examples, see Path examples. '/' (root path) callback
Callback functions; can be:
中間件功能。
一系列中間件功能(用逗號分隔)。
一系列中間件功能。
以上所有組合。
您可以提供多個回調函數(shù),其行為與中間件類似,只是這些回調可以調用next('route')
繞過剩余的路由回調。您可以使用此機制在路線上施加先決條件,并在沒有理由繼續(xù)使用當前路線時將控制權交給后續(xù)路線。
由于路由器和應用程序實現(xiàn)了中間件接口,因此您可以像使用其他中間件功能一樣使用它們。
有關示例,請參閱中間件回調函數(shù)示例。
無
有關更多信息,請參閱路由指南。
app.get('/', function (req, res) { res.send('GET request to homepage');});
啟動一個UNIX套接字并給定路徑上的連接。此方法與Node的http.Server.listen()相同。
var express = require('express'); var app = express();app.listen('/tmp/sock');
綁定并偵聽指定主機和端口上的連接。此方法與Node的http.Server.listen()相同。
var express = require('express'); var app = express();app.listen(3000);
在app
返回的express()
實際上是一個JavaScript Function
,旨在傳遞到節(jié)點的HTTP服務器作為一個回調來處理請求。這使得您可以輕松地使用相同的代碼庫為您的應用程序提供HTTP和HTTPS版本,因為應用程序不會從這些應用程序繼承(它只是一個回調):
var express = require('express'); var https = require('https'); var http = require('http'); var app = express(); http.createServer(app).listen(80); https.createServer(options, app).listen(443);
app.listen()
方法返回一個http.Server對象,并且(對于HTTP)對于以下是一個方便的方法:
app.listen = function() { var server = http.createServer(this); return server.listen.apply(server, arguments); };
路由HTTP請求,其中METHOD是請求的HTTP方法,例如GET,PUT,POST等,小寫形式。因此,實際的方法是app.get()
,app.post()
,app.put()
,等等。請參閱下面的路由方法以獲取完整列表。
參數(shù) | 描述 | 默認 |
---|---|---|
path | 中間件功能被調用的路徑; 可以是以下任何一種:表示路徑的字符串。路徑模式。一個正則表達式模式來匹配路徑。上述任何組合的數(shù)組。有關示例,請參閱路徑示例。 | '/' (root path) |
callback | 回調函數(shù);可以是:中間件功能。一系列中間件功能(用逗號分隔)。一系列中間件功能。以上所有組合。您可以提供多個回調函數(shù),其行為就像中間件一樣,只不過這些回調可以調用next('route')來繞過剩余的路由回調。您可以使用此機制在路線上施加先決條件,并在沒有理由繼續(xù)使用當前路線時將控制權交給后續(xù)路線。由于路由器和應用程序實現(xiàn)了中間件接口,因此您可以像使用其他中間件功能一樣使用它們。有關示例,請參閱中間件回調函數(shù)示例。 | None |
表示路徑的字符串。
路徑模式。
一個正則表達式模式來匹配路徑。
上述任何組合的數(shù)組。
有關示例,請參閱路徑示例 '/' (root path) callback
回調函數(shù);可以是:
中間件功能。
一系列中間件功能(用逗號分隔)。
一系列中間件功能。
以上所有組合。
您可以提供多個回調函數(shù),其行為與中間件類似,只是這些回調可以調用next('route')
繞過剩余的路由回調。您可以使用此機制在路線上施加先決條件,并在沒有理由繼續(xù)使用當前路線時將控制權交給后續(xù)路線。
由于路由器和應用程序實現(xiàn)了中間件接口,因此您可以像使用其他中間件功能一樣使用它們。
有關示例,請參閱中間件回調函數(shù)示例。
無
Express支持以下與相同名稱的HTTP方法相對應的路由方法:
checkout copy delete get head lock merge mkactivity | mkcol move m-search notify options patch post | purge put report search subscribe trace unlock unsubscribe |
---|
checkout
copy
delete
get
head
lock
merge
mkactivity
mkcol
move
m-search
notify
options
patch
post
purge
put
report
search
subscribe
trace
unlock
unsubscribe
API文檔中有明確的項目只針對最流行的HTTP方法app.get()
,app.post()
,app.put()
,和app.delete()
。但是,上面列出的其他方法的工作方式完全相同。
要路由轉換為無效JavaScript變量名稱的方法,請使用括號表示法。例如,app['m-search']('/', function ...
。
除了GET
方法之外,如果以前app.head()
沒有在app.get()
之前被路徑app.get()
調用該函數(shù),則會自動為HTTP HEAD
方法調用該函數(shù)。
方法app.all()
不是從任何HTTP方法派生的,并為所有 HTTP請求方法的指定路徑加載中間件。有關更多信息,請參閱app.all。
有關路由的更多信息,請參閱路由指南。
添加回調觸發(fā)器來路由參數(shù),其中name
是參數(shù)的名稱或它們的數(shù)組,并且callback
是回調函數(shù)?;卣{函數(shù)的參數(shù)依次為請求對象,響應對象,下一個中間件,參數(shù)值和參數(shù)名稱。
如果name
是數(shù)組,callback
則為其中聲明的每個參數(shù)以觸發(fā)器的聲明順序注冊觸發(fā)器。此外,除了最后一個聲明的參數(shù)外,next
對回調函數(shù)內部的調用將調用下一個聲明參數(shù)的回調函數(shù)。對于最后一個參數(shù),調用next
將為當前正在處理的路由調用下一個中間件,就像它name
只是一個字符串一樣。
例如,當:user
存在于路徑路徑中時,您可以映射用戶加載邏輯以自動提供req.user
給路徑,或對參數(shù)輸入執(zhí)行驗證。
app.param('user', function(req, res, next, id) { // try to get the user details from the User model and attach it to the request object User.find(id, function(err, user) { if (err) { next(err); } else if (user) { req.user = user; next(); } else { next(new Error('failed to load user')); } });});
Param回調函數(shù)在它們被定義的路由器的本地。它們不會被安裝的應用程序或路由器繼承。因此,定義的參數(shù)回調app
將僅由路由上定義的路由參數(shù)觸發(fā)app
。
所有param回調函數(shù)都將在param出現(xiàn)的任何路由的任何處理程序之前被調用,并且它們將在請求 - 響應循環(huán)中僅被調用一次,即使參數(shù)在多個路由中匹配,如以下示例所示。
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 matches 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) { console.log('and this matches too'); res.end();});
在GET /user/42/3
,打印如下:
CALLED ONLY ONCE with 42CALLED ONLY ONCE with 3although this matches and this matches too
以下部分描述了app.param(callback)
從v4.11.0開始不推薦使用的部分。
app.param(name, callback)
方法的行為可以完全通過只傳遞一個函數(shù)來改變app.param()
。這個函數(shù)是一個app.param(name, callback)
應該如何行為的自定義實現(xiàn)- 它接受兩個參數(shù)并且必須返回一個中間件。
此函數(shù)的第一個參數(shù)是應該捕獲的URL參數(shù)的名稱,第二個參數(shù)可以是可用于返回中間件實現(xiàn)的任何JavaScript對象。
該函數(shù)返回的中間件決定捕獲URL參數(shù)時發(fā)生的行為。
在這個例子中,app.param(name, callback)
簽名被修改為app.param(name, accessId)
。app.param()
現(xiàn)在接受一個名字和一個數(shù)字,而不是接受一個名字和一個回調。
var express = require('express'); var app = express();// customizing the behavior of app.param() app.param(function(param, option) { return function (req, res, next, val) { if (val == option) { next(); } else { next('route'); } }});// using the customized app.param() app.param('id', 1337);// route to trigger the capture app.get('/user/:id', function (req, res) { res.send('OK');});app.listen(3000, function () { console.log('Ready');});
在此示例中,app.param(name, callback)
簽名保持不變,但不是中間件回調,而是定義了自定義數(shù)據(jù)類型檢查函數(shù)來驗證用戶標識的數(shù)據(jù)類型。
app.param(function(param, validator) { return function (req, res, next, val) { if (validator(val)) { next(); } else { next('route'); } }}); app.param('id', function (candidate) { return !isNaN(parseFloat(candidate)) && isFinite(candidate);});
' .
'字符不能用于捕獲捕獲正則表達式中的字符。例如,你不能用'/user-.+/'
來捕捉'users-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);
返回應用程序的規(guī)范路徑,一個字符串。
var app = express() , blog = express() , blogAdmin = express(); app.use('/blog', blog); blog.use('/admin', blogAdmin); console.log(app.path()); // ''console.log(blog.path()); // '/blog'console.log(blogAdmin.path()); // '/blog/admin'
在安裝應用程序的復雜情況下,此方法的行為可能會變得非常復雜:通常使用req.baseUrl獲取應用程序的規(guī)范路徑會更好。
使用指定的回調函數(shù)將HTTP POST請求路由到指定的路徑。有關更多信息,請參閱路由指南。
參數(shù) | 描述 | 默認 |
---|---|---|
path | 中間件功能被調用的路徑;可以是以下任何一種:表示路徑的字符串、路徑模式和正則表達式模式來匹配路徑,或上述任何組合的數(shù)組。有關示例,請參閱路徑示例。 | '/' (root path) |
callback | 回調函數(shù);可以是:中間件功能、一系列中間件功能(用逗號分隔)、一系列中間件功能,或以上所有組合。您可以提供多個回調函數(shù),其行為就像中間件一樣,只不過這些回調可以調用next('route')來繞過剩余的路由回調。您可以使用此機制在路線上施加先決條件,并在沒有理由繼續(xù)使用當前路線時將控制權交給后續(xù)路線。由于路由器和應用程序實現(xiàn)了中間件接口,因此您可以像使用其他中間件功能一樣使用它們。有關示例,請參閱中間件回調函數(shù)示例。 | None |
表示路徑的字符串。
路徑模式。
一個正則表達式模式來匹配路徑。
上述任何組合的數(shù)組。
有關示例,請參閱路徑示例,'/' (root path) callback
回調函數(shù);可以是:
中間件功能。
一系列中間件功能(用逗號分隔)。
一系列中間件功能。
以上所有組合。
您可以提供多個回調函數(shù),其行為與中間件類似,只是這些回調可以調用next('route')
繞過剩余的路由回調。您可以使用此機制在路線上施加先決條件,并在沒有理由繼續(xù)使用當前路線時將控制權交給后續(xù)路線。
由于路由器和應用程序實現(xiàn)了中間件接口,因此您可以像使用其他中間件功能一樣使用它們。
有關示例,請參閱中間件回調函數(shù)示例。
無
app.post('/', function (req, res) { res.send('POST request to homepage');});
使用指定的回調函數(shù)將HTTP PUT請求路由到指定的路徑。
參數(shù) | 描述 | 默認 |
---|---|---|
path | 中間件功能被調用的路徑;可以是以下任何一種:表示路徑的字符串、路徑模式、一個正則表達式模式來匹配路徑以及上述任何組合的數(shù)組。有關示例,請參閱路徑示例。 | '/' (root path) |
callback | 回調函數(shù);可以是:中間件功能、一系列中間件功能(用逗號分隔)、一系列中間件功能,及以上所有組合。您可以提供多個回調函數(shù),其行為就像中間件一樣,只不過這些回調可以調用next('route')來繞過剩余的路由回調。您可以使用此機制在路線上施加先決條件,并在沒有理由繼續(xù)使用當前路線時將控制權交給后續(xù)路線。由于路由器和應用程序實現(xiàn)了中間件接口,因此您可以像使用其他中間件功能一樣使用它們。有關示例,請參閱中間件回調函數(shù)示例。 | None |
表示路徑的字符串。
路徑模式。
一個正則表達式模式來匹配路徑。
上述任何組合的數(shù)組。
有關示例,請參閱路徑示例。 '/' (root path)callback
回調函數(shù); 可以是:
中間件功能。
一系列中間件功能(用逗號分隔)。
一系列中間件功能。
以上所有組合。
您可以提供多個回調函數(shù),其行為與中間件類似,只是這些回調可以調用next('route')
繞過剩余的路由回調。您可以使用此機制在路線上施加先決條件,并在沒有理由繼續(xù)使用當前路線時將控制權交給后續(xù)路線。
由于路由器和應用程序實現(xiàn)了中間件接口,因此您可以像使用其他中間件功能一樣使用它們。
有關示例,請參閱中間件回調函數(shù)示例。
無
app.put('/', function (req, res) { res.send('PUT request to homepage');});
通過callback
函數(shù)返回視圖的呈現(xiàn)HTML 。它接受一個可選參數(shù),該參數(shù)是包含視圖的局部變量的對象。它就像res.render()一樣,除了它不能將渲染視圖自己發(fā)送到客戶端。
將其app.render()
視為用于生成呈現(xiàn)視圖字符串的實用程序函數(shù)。內部res.render()
用于app.render()
渲染視圖。
本地變量cache
保留用于啟用視圖緩存。如果您想在開發(fā)期間緩存視圖將其設置為true
;在生產(chǎn)中默認啟用視圖緩存。
app.render('email', function(err, html){ // ...}); app.render('email', { name: 'Tobi' }, function(err, html){ // ...});
返回單個路由的實例,然后您可以使用該實例來處理具有可選中間件的HTTP動詞。使用app.route()
以避免重復路線名稱(因此出現(xiàn)打字錯誤)。
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...});
分配設置name
給value
。您可以存儲您想要的任何值,但某些名稱可用于配置服務器的行為。這些特殊名稱在應用程序設置表中列出。
調用app.set('foo', true)
作為布爾屬性與調用app.enable('foo')
相同。同樣,調用app.set('foo', false)
作為布爾屬性與調用app.disable('foo')
相同。
用app.get()
檢索設置的值。
app.set('title', 'My Site'); app.get('title'); // "My Site"
下表列出了應用程序設置。
請注意,子應用程序將:
不繼承具有默認值的設置的值。您必須在子應用程序中設置值。
繼承沒有默認值的設置值; 這些在下表中明確指出。
例外情況:子應用程序將繼承trust proxy
的值,即使它具有默認值(用于向后兼容)。子應用程序不會繼承view cache
生產(chǎn)中的價值(當NODE_ENV
是“production”)。
屬性 | 類型 | 描述 | 默認 |
---|---|---|---|
case sensitive routing | 布爾 | 啟用區(qū)分大小寫。啟用時,“/ Foo”和“/ foo”是不同的路線。禁用時,“/ Foo”和“/ foo”的處理方式相同。注意:子應用程序將繼承此設置的值。 | N/A (undefined) |
env | 串 | 環(huán)境模式。確保在生產(chǎn)環(huán)境中設置為“生產(chǎn)”; 請參閱生產(chǎn)最佳實踐:性能和可靠性。 | process.env.NODE_ENV (NODE_ENV environment variable) or “development” if NODE_ENV is not set. |
etag | 多變 | 設置ETag響應標題。有關可能的值,請參閱etag選項表。有關HTTP ETag標頭的更多信息。 | weak |
jsonp callback name | 串 | 指定默認的JSONP回調名稱。 | “callback” |
json escape | 布爾 | 啟用從res.json,res.jsonp和res.send API轉義的JSON響應。這將在JSON中轉義字符<,>和&作為Unicode轉義序列。這樣做的目的是當客戶端嗅探HTML響應時協(xié)助減輕某些類型的持續(xù)XSS攻擊。注意:子應用程序將繼承此設置的值。 | N/A (undefined) |
json replacer | 多變 | '替代者'論證使用的JSON.stringify。注意:子應用程序將繼承此設置的值。 | N/A (undefined) |
json spaces | 多變 | “空間”論證使用JSON.stringify。這通常設置為用于縮進美化JSON的空格數(shù)量。注意:子應用程序將繼承此設置的值。 | N/A (undefined) |
query parser | 多變 | 通過將該值設置為false來禁用查詢分析,或者將查詢分析器設置為使用“簡單”或“擴展”或自定義查詢字符串分析功能。簡單的查詢解析器基于Node的本地查詢解析器querystring。擴展查詢解析器基于qs。自定義查詢字符串解析函數(shù)將接收完整的查詢字符串,并且必須返回查詢關鍵字及其值的對象。 | "extended" |
strict routing | 布爾 | 啟用嚴格的路由。啟用時,路由器將“/ foo”和“/ foo /”視為不同。否則,路由器將“/ foo”和“/ foo /”視為相同。注意:子應用程序將繼承此設置的值。 | N/A (undefined) |
subdomain offset | 數(shù) | 要移除以訪問子域的主機的點分離部分的數(shù)量。 | 2 |
trust proxy | 多變 | 指示應用程序位于前置代理后面,并使用X-Forwarded- *標題確定客戶端的連接和IP地址。注:X-Forwarded- *標頭很容易被欺騙,檢測到的IP地址不可靠。啟用后,Express會嘗試確定通過前置代理或一系列代理連接的客戶端的IP地址。該req.ips屬性然后包含客戶端連接的一組IP地址。要啟用它,請使用信任代理選項表中描述的值。該trust proxy設置是使用proxy-addr軟件包實現(xiàn)的。有關更多信息,請參閱其文檔。注:子應用程序將繼承此設置的值,即使它具有默認值。 | false (disabled) |
views | 字符串或數(shù)組 | 應用程序視圖的目錄或目錄數(shù)組。如果是數(shù)組,那么視圖按照它們在數(shù)組中出現(xiàn)的順序查找。 | process.cwd()+'/ views' |
view cache | 布爾 | 啟用視圖模板編譯緩存。注意:子應用程序不會繼承生產(chǎn)中此設置的值(何時NODE\_ENV為“生產(chǎn)”)。 | true in production, otherwise undefined. |
view engine | 串 | 省略時使用的默認引擎擴展。注意:子應用程序將繼承此設置的值。 | N/A (undefined) |
x-powered-by | 布爾 | 啟用“X-Powered-By:Express”HTTP標頭。 | true |
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地址:
指定一個子網(wǎng):
app.set('trust proxy', 'loopback')
指定一個子網(wǎng)和一個地址:
app.set('trust proxy', 'loopback, 123.123.123.123')
指定多個子網(wǎng)為CSV:
app.set('trust proxy', 'loopback, linklocal, uniquelocal')
將多個子網(wǎng)指定為一個數(shù)組:
app.set('trust proxy', 'loopback', 'linklocal', 'uniquelocal')
指定時,將從地址確定過程中排除IP地址或子網(wǎng),并將離應用程序服務器最近的不可信IP地址確定為客戶端的IP地址。
Number Trust the _n_th hop from the front-facing proxy server as the client.
Function Custom trust implementation. Use this only if you know what you are doing.
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` setting
注:這些設置僅適用于動態(tài)文件,而不適用于靜態(tài)文件。express.static中間件忽略這些設置。
ETag功能是使用etag軟件包實現(xiàn)的。有關更多信息,請參閱其文檔。
類型值布爾值 true
啟用弱ETag。這是默認設置。
false
完全禁用ETag。
String If "strong", enables strong ETag.
如果“weak”,弱化ETag。函數(shù)自定義ETag函數(shù)的實現(xiàn)。只有當你知道你在做什么時才使用。
app.set('etag', function (body, encoding) { return generateHash(body, encoding); // consider the function is defined });
在指定的路徑上安裝指定的中間件功能或中間件功能:當請求的路徑的基礎匹配時,執(zhí)行中間件功能path
。
參數(shù) | 描述 | 默認 |
---|---|---|
path | 中間件功能被調用的路徑;可以是以下任何一種:表示路徑的字符串、路徑模式、一個正則表達式模式來匹配路徑、或上述任何組合的數(shù)組。有關示例,請參閱路徑示例。 | '/' (root path) |
callback | 回調函數(shù); 可以是:中間件功能、一系列中間件功能(用逗號分隔)、一系列中間件功能、或以上所有組合。您可以提供多個回調函數(shù),其行為就像中間件一樣,只不過這些回調可以調用next('route')來繞過剩余的路由回調。您可以使用此機制在路線上施加先決條件,并在沒有理由繼續(xù)使用當前路線時將控制權交給后續(xù)路線。由于路由器和應用程序實現(xiàn)了中間件接口,因此您可以像使用其他中間件功能一樣使用它們。有關示例,請參閱中間件回調函數(shù)示例。 | None |
表示路徑的字符串。
路徑模式。
一個正則表達式模式來匹配路徑。
上述任何組合的數(shù)組。
有關示例,請參閱路徑示例'/' (root path)callback
回調函數(shù);可以是:
中間件功能。
一系列中間件功能(用逗號分隔)。
一系列中間件功能。
以上所有組合。
您可以提供多個回調函數(shù),其行為與中間件類似,只是這些回調可以調用next('route')
繞過剩余的路由回調。您可以使用此機制在路線上施加先決條件,并在沒有理由繼續(xù)使用當前路線時將控制權交給后續(xù)路線。
由于路由器和應用程序實現(xiàn)了中間件接口,因此您可以像使用其他中間件功能一樣使用它們。
For examples, see Middleware callback function examples.
空
一條路徑將立即匹配其路徑后跟一個“ /
”的任何路徑。例如:app.use('/apple', ...)
將匹配“/ apple”,“/ apple / images”,“/ apple / images / news”等。
由于path
缺省設置為“/”,因此無需路徑安裝的中間件將針對應用程序的每個請求執(zhí)行。
例如,該中間件功能將針對應用程序的每個請求執(zhí)行:
app.use(function (req, res, next) { console.log('Time: %d', Date.now()); next();});
注意
子應用程序將:
不繼承具有默認值的設置的值。您必須在子應用程序中設置值。
繼承沒有默認值的設置值。
有關詳情,請參閱應用程序設置
中間件功能是按順序執(zhí)行的,因此中間件包含的順序非常重要。
// this middleware will not allow the request to go beyond itapp.use(function(req, res, next) { res.send('Hello World');});// requests will never reach this routeapp.get('/', function (req, res) { res.send('Welcome');});
錯誤處理中間件
錯誤處理中間件始終需要四個參數(shù)。您必須提供四個參數(shù)來將其標識為錯誤處理中間件功能。即使您不需要使用該next
對象,也必須指定它以維護簽名。否則,該next
對象將被解釋為常規(guī)中間件,并且將無法處理錯誤。有關錯誤處理中間件的詳細信息,請參閱:錯誤處理。
使用與其他中間件功能相同的方式定義錯誤處理中間件函數(shù),除了使用四個參數(shù)而不是三個參數(shù),特別是簽名(err, req, res, next)
):
app.use(function(err, req, res, next) { console.error(err.stack); res.status(500).send('Something broke!');});
下表提供了一些path
有關安裝中間件的有效值的簡單示例。
類型 | 示例 |
---|---|
路徑 | 這將匹配從以下開始的路徑/abcd:app.use('/ abcd',function(req,res,next){next();}); |
路徑模式 | 這將匹配以/abcd和開頭的路徑/abd:app.use('/ abc?d',function(req,res,next){next();}); 這將匹配開始路徑/abcd,/abbcd,/abbbbbcd,等:app.use( '/ AB + CD',功能(REQ,RES,下一個){下一個();}); 這將匹配開始路徑/abcd,/abxcd,/abFOOcd,/abbArcd,等:app.use( '/ AB \ * CD',功能(REQ,RES,下一個){下一個();}); 這將匹配以/ad和開頭的路徑/abcd:app.use('/ a(bc)?d',function(req,res,next){next();}); |
正則表達式 | 這將匹配以/abc和開頭的路徑/xyz:app.use(/ \ / abc | \ / xyz /,function(req,res,next){next();}); |
排列 | 這將匹配的路徑開始/abcd,/xyza,/lmn,和/pqr:app.use( '/ ABCD', '/ XYZA',/ \ / LMN | \ / PQR /,功能(REQ,RES,下一個){下一個();}) ; |
下表提供了可被用作的中間件功能一些簡單的例子callback
參數(shù)app.use()
,app.METHOD()
和app.all()
。盡管例子是app.use()
,它們也適用于app.use()
,app.METHOD()
和app.all()
。
用法 | 示例 |
---|---|
單一中間件 | 您可以在本地定義和安裝中間件功能。app.use(function(req,res,next){next();}); 路由器是有效的中間件。var router = express.Router(); router.get('/',function(req,res,next){next();}); app.use(路由器); 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); |
排列 | 使用數(shù)組從邏輯上將中間件分組。如果您將一組中間件作為第一個或唯一的中間件參數(shù)傳遞,那么您必須指定安裝路徑。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); |
組合 | 您可以結合上述所有安裝中間件的方式。函數(shù)mw1(req,res,next){next(); }函數(shù)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中間件的一些示例。
從應用程序目錄中的“公共”目錄為應用程序提供靜態(tài)內容:
// GET /style.css etcapp.use(express.static(__dirname + '/public'));
僅當中間件的請求路徑前綴為“/ static”時,才將中間件裝入“/ static”以提供靜態(tài)內容:
// GET /static/style.css etc.app.use('/static', express.static(__dirname + '/public'));
通過在靜態(tài)中間件之后加載記錄器中間件來禁用對靜態(tài)內容請求的記錄:
app.use(express.static(__dirname + '/public'));app.use(logger());
從多個目錄提供靜態(tài)文件,但優(yōu)先于其他目錄的“./public”:
app.use(express.static(__dirname + '/public'));app.use(express.static(__dirname + '/files'));app.use(express.static(__dirname + '/uploads'));
req
對象表示HTTP請求,并具有請求查詢字符串,參數(shù),正文,HTTP標頭等的屬性。在本文檔中,按照慣例,該對象總是被稱為req
(并且HTTP響應是res
),但其實際名稱由您正在工作的回調函數(shù)的參數(shù)決定。
例如:
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);});
req
對象是Node自身請求對象的增強版本,并支持所有內置字段和方法。
在Express 4中,默認情況下req.files
在req
對象中不再可用。要訪問req.files
對象上的上傳文件,請使用多部件處理中間件,如busboy,multer,formidable,multiparty,connect-multiparty或pez。
該屬性包含對使用中間件的Express應用程序實例的引用。
如果您遵循創(chuàng)建模塊的模式,該模塊只是將中間件功能導出并將require()
其存儲在主文件中,那么中間件可以通過req.app
以下方式訪問Express實例:
例如:
//index.jsapp.get('/viewdirectory', require('./mymiddleware.js'))
//mymiddleware.jsmodule.exports = function (req, res) { res.send('The views directory is ' + req.app.get('views'));});
路由器實例安裝的URL路徑。
req.baseUrl
屬性與app
對象的mountpath屬性相似,但app.mountpath
返回匹配的路徑模式。
例如:
var greet = express.Router();greet.get('/jp', function (req, res) { console.log(req.baseUrl); // /greet res.send('Konichiwa!');});app.use('/greet', greet); // load the router on '/greet'
即使您使用路徑模式或一組路徑模式來加載路由器,該baseUrl
屬性也會返回匹配的字符串,而不是模式。在以下示例中,greet
路由器以兩種路徑模式加載。
app.use(['/gre+t', '/hel{2}o'], greet); // load the router on '/gre+t' and '/hel{2}o'
當向/greet/jp
,req.baseUrl
提出的請求是“/greet”。當向/hello/jp
提出的請求是,req.baseUrl
是“/ hello”。
包含請求正文中提交的鍵值對數(shù)據(jù)。默認情況下,是undefined
。使用body-parser和multer等body分析中間件時被填充。
以下示例顯示如何使用body分析中間件來填充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);});
在使用Cookie解析器中間件時,此屬性是包含請求發(fā)送的Cookie的對象。如果請求不包含cookie,則默認為{}
。
// Cookie: name=tjreq.cookies.name// => "tj"
如果cookie已被簽名,則必須使用req.signedCookies。
有關更多信息,問題或疑慮,請參閱cookie解析器。
指示請求是否為“fresh”。與此相反req.stale
。
如果cache-control
請求頭沒有no-cache
指令并且下列任何一個都為真,那么這是真的:
if-modified-since
請求標頭中指定和last-modified
請求標頭是等于或早于modified
響應。
if-none-match
請求標頭是*
。
if-none-match
請求標頭中,在被解析成它的指令,不匹配etag
的響應標頭。
req.fresh// => true
有關更多信息,問題或疑慮,請參閱全新。
包含從Host
HTTP頭派生的主機名。
當trust proxy
設置不計算時false
,此屬性將改為具有X-Forwarded-Host
標題字段的值。這個標頭可以由客戶端或代理來設置。
// Host: "example.com:3000"req.hostname// => "example.com"
包含請求的遠程IP地址。
當trust proxy
設置不計算到false
時,此屬性的值將從頭中最左邊的條目派生X-Forwarded-For
。這個標頭可以由客戶端或代理來設置。
req.ip// => "127.0.0.1"
當trust proxy
設置不計算false
時,該屬性包含X-Forwarded-For
請求頭中指定的IP地址數(shù)組。否則,它包含一個空數(shù)組。這個頭可以由客戶端或代理來設置。
例如,如果X-Forwarded-For
是client, proxy1, proxy2
,req.ips
將是["client", "proxy1", "proxy2"]
,其中proxy2
是下游最遠的。
包含對應于該請求的HTTP方法的字符串:GET
,POST
,PUT
,等。
req.url
不是本機Express特性,它是從Node的http模塊繼承而來的。
這個屬性很像req.url
; 但是,它保留了原始的請求URL,允許您req.url
為內部路由目的自由重寫。例如,app.use()的“掛載”功能將重寫req.url
以剝離掛載點。
// GET /search?q=somethingreq.originalUrl// => "/search?q=something"
在中間件功能,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' next();});
該屬性是一個包含映射到指定路由“參數(shù)”的屬性的對象。例如,如果您有路線/user/:name
,那么“名稱”屬性可用req.params.name
。該對象默認為{}
。
// GET /user/tjreq.params.name// => "tj"
當為路由定義使用正則表達式時,使用的數(shù)組中提供了捕獲組req.params[n]
,其中n
是第n個捕獲組。此規(guī)則適用于具有字符串路由的未命名通配符匹配,例如/file/*
:
// GET /file/javascripts/jquery.jsreq.params[0]// => "javascripts/jquery.js"
如果您需要對鍵進行更改req.params
,請使用app.param處理程序。更改僅適用于已在路徑路徑中定義的參數(shù)。
對req.params
中間件或路由處理程序中的對象所做的任何更改都將被重置。
包含請求URL的路徑部分。
// example.com/users?sort=descreq.path// => "/users"
從中間件調用時,掛載點不包含在內req.path
。有關更多詳細信息,請參閱app.use()。
包含請求協(xié)議字符串:http
或者(for TLES requests)https
。
如果trust proxy
設置不計算為false
,則此屬性將使用X-Forwarded-Proto
標題字段的值(如果存在)。這個標頭可以由客戶端或代理來設置。
req.protocol// => "http"
此屬性是包含路由中每個查詢字符串參數(shù)的屬性的對象。如果沒有查詢字符串,它是空的對象,{}
。
// GET /search?q=tobi+ferretreq.query.q// => "tobi ferret"// GET /shoes?order=desc&shoe[color]=blue&shoe[type]=conversereq.query.order// => "desc"req.query.shoe.color// => "blue"req.query.shoe.type// => "converse"
包含當前匹配的路由,一個字符串。例如:
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 } }
一個Boolean屬性,如果建立了TLS連接,則為true。相當于:
'https' == req.protocol;
當使用cookie解析器中間件時,該屬性包含請求發(fā)送的簽名cookie,未簽名并可以使用。簽名的cookies位于不同的對象中以顯示開發(fā)者的意圖;否則,可能會對req.cookie
值進行惡意攻擊(這很容易被欺騙)。請注意,簽名cookie不會使其“隱藏”或加密;但只是防止篡改(因為用于簽名的秘密是私密的)。
如果未發(fā)送簽名的cookie,則屬性默認為{}
。
// Cookie: user=tobi.CP7AWaXDfAKIRfH49dQzKJx7sKzzSoPq7/AcBBRVwlI3req.signedCookies.user// => "tobi"
有關更多信息,問題或疑慮,請參閱cookie解析器。
指示請求是否為“stale”,還是與之相反req.fresh
。有關更多信息,請參閱req.fresh。
req.stale// => true
請求的域名中的一組子域。
// Host: "tobi.ferrets.example.com"req.subdomains// => ["ferrets", "tobi"]
應用程序屬性subdomain offset
(默認為2)用于確定子域分段的開始。要更改此行為,請使用app.set更改其值。
一個布爾屬性,true
如果請求的X-Requested-With
頭部字段是“XMLHttpRequest”,則表示該請求是由諸如jQuery之類的客戶端庫發(fā)出的。
req.xhr// => true
根據(jù)請求的Accept
HTTP頭字段檢查指定的內容類型是否可接受。該方法返回最佳匹配,或者如果沒有指定的內容類型是可接受的,則返回false
(在這種情況下,應用程序應回應406 "Not Acceptable"
)。
type
值可以是單個MIME類型的字符串(如“application / json”),擴展名稱(如“json”),逗號分隔列表或數(shù)組。對于列表或數(shù)組,該方法返回最佳匹配(如果有)。
// Accept: text/htmlreq.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"
根據(jù)請求的Accept-Charset
HTTP頭字段返回指定字符集的第一個接受字符集。如果沒有指定的字符集被接受,則返回false
。
根據(jù)請求的Accept-Encoding
HTTP頭字段返回指定編碼的第一個可接受的編碼。如果沒有指定的編碼被接受,則返回false
。
根據(jù)請求的Accept-Language
HTTP頭字段返回指定語言的第一個接受的語言。如果沒有指定的語言被接受,則返回false
。
返回指定的HTTP請求標頭字段(不區(qū)分大小寫的匹配)。在Referrer
和Referer
領域是可以互換的。
req.get('Content-Type');// => "text/plain"req.get('content-type');// => "text/plain"req.get('Something');// => undefined
別名為req.header(field)
。
如果傳入請求的“Content-Type”HTTP標頭字段與type
參數(shù)指定的MIME類型相匹配,則返回匹配的內容類型。否則返回false
。
// With Content-Type: text/html; charset=utf-8req.is('html'); // => 'html' req.is('text/html'); // => 'text/html' req.is('text/*'); // => 'text/*' // When Content-Type is application/json req.is('json'); // => 'json' req.is('application/json'); // => 'application/json' req.is('application/*'); // => 'application/*' req.is('html'); // => false
已過時。二者必選其一req.params
,req.body
或req.query
(如適用)。
當存在時返回參數(shù)name
的值。
// ?name=tobi req.param('name')// => "tobi" // POST name=tobi req.param('name')// => "tobi" // /user/tobi for /user/:name req.param('name')// => "tobi"
查找按以下順序執(zhí)行:
req.params
req.body
req.query
或者,如果在任何請求對象中找不到該參數(shù),則可以指定defaultValue
設置默認值。
直接訪問req.body
,req.params
以及req.query
應該贊成清晰-除非你真正接受來自每個對象的輸入。
body解析中間件必須被加載以便req.param()
可預測地工作。詳情請參閱req.body。
Range
標頭解析器。
該size
參數(shù)是資源的最大大小。
options
參數(shù)是一個可以具有以下屬性的對象。
屬性 | 類型 | 描述 |
---|---|---|
combine | Boolean | 指定是否重疊和相鄰范圍應該組合,默認為false。如果為true,范圍將被組合并返回,就像它們在標題中指定的那樣。 |
將返回范圍數(shù)組或表示錯誤解析的負數(shù)。
-2
表示格式錯誤的標題字符串
-1
表示不可滿足的范圍
// parse header from requestvar range = req.range(1000)// the type of the rangeif (range.type === 'bytes') { // the ranges range.forEach(function (r) { // do something with r.start and r.end })}
res
對象表示Express應用程序在獲取HTTP請求時發(fā)送的HTTP響應。
在本文檔中,按照慣例,對象始終被稱為res
(并且HTTP請求是req
),但其實際名稱由您正在其中工作的回調函數(shù)的參數(shù)確定。
例如:
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);});
res
對象是Node自身響應對象的增強版本,并支持所有內置字段和方法。
該屬性包含對使用中間件的Express應用程序實例的引用。
res.app
與請求對象中的req.app屬性相同。
指示應用程序是否為響應發(fā)送HTTP標頭的布爾屬性。
app.get('/', function (req, res) { console.log(res.headersSent); // false res.send('OK'); console.log(res.headersSent); // true});
一個對象,其中包含作用域為請求的響應局部變量,因此僅可用于請求/響應周期期間呈現(xiàn)的視圖(如果有)。否則,該屬性與app.locals相同。
此屬性對于公開請求級別信息(例如請求路徑名稱,已驗證用戶,用戶設置等)非常有用。
app.use(function(req, res, next){ res.locals.user = req.user; res.locals.authenticated = ! req.user.anonymous; next();});
res.append()
由Express v4.11.0 +支持
將指定的附加value
到HTTP響應標頭field
。如果標題尚未設置,則會使用指定的值創(chuàng)建標題。該value
參數(shù)可以是字符串或數(shù)組。
注:調用res.set()
之后res.append()
將重置先前設置的標頭值。
res.append('Link', ['<http://localhost/>', '<http://localhost:3000/>']); res.append('Set-Cookie', 'foo=bar; Path=/; HttpOnly'); res.append('Warning', '199 Miscellaneous warning');
將HTTP響應Content-Disposition
標題字段設置為“附件”。如果給出filename
,那么它通過擴展名設置Content-Type res.type()
,并設置Content-Disposition
“filename =”參數(shù)。
res.attachment();// Content-Disposition: attachmentres.attachment('path/to/logo.png'); // Content-Disposition: attachment; filename="logo.png"// Content-Type: image/png
將cookiename
設置為value
。該value
參數(shù)可能是一個字符串或對象轉換為JSON。
options
參數(shù)是一個可以具有以下屬性的對象。
屬性 | 類型 | 描述 |
---|---|---|
domain | String | Cookie的域名。默認為應用程序的域名。 |
encode | Function | 用于cookie值編碼的同步函數(shù)。默認為encodeURIComponent。 |
expires | Dat | 以GMT格式的cookie的有效日期。如果未指定或設置為0,則創(chuàng)建會話cookie。 |
httpOnly | Boolean | 將cookie標記為僅可由Web服務器訪問。 |
maxAge | Number | 方便的選項,用于設置相對于當前時間的到期時間(以毫秒為單位)。 |
path | String | Cookie的路徑。默認為“/”。 |
secure | Boolean | 將cookie標記為僅與HTTPS一起使用。 |
signed | Boolean | 指示是否應該對cookie進行簽名。 |
sameSit | Boolean or String | “SameSite”Set-Cookie屬性的值。更多信息請訪問https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00#section-4.1.1。 |
所有的res.cookie()
操作都是Set-Cookie
使用提供的選項設置HTTP 標頭。任何未指定的選項都默認為RFC 6265中規(guī)定的值。
例如:
res.cookie('name', 'tobi', { domain: '.example.com', path: '/admin', secure: true }); res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true });
encode
選項允許您選擇用于cookie值編碼的功能。不支持異步功能。
示例用例:您需要為組織中的其他站點設置一個域范圍的cookie。這個其他網(wǎng)站(不在您的管理控制下)不使用URI編碼的cookie值。
//Default encoding res.cookie('some_cross_domain_cookie', 'http://mysubdomain.example.com',{domain:'example.com'}); // Result: 'some_cross_domain_cookie=http%3A%2F%2Fmysubdomain.example.com; Domain=example.com; Path=/'//Custom encodingres.cookie('some_cross_domain_cookie', 'http://mysubdomain.example.com', {domain:'example.com', encode: String});// Result: 'some_cross_domain_cookie=http://mysubdomain.example.com; Domain=example.com; Path=/;'
maxAge
選項是一個方便的選項,用于設置相對于當前時間的“過期”(以毫秒為單位)。以下相當于上面的第二個例子。
res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true });
您可以傳遞一個對象作為value
參數(shù); 然后將其序列化為JSON并由bodyParser()
中間件進行分析。
res.cookie('cart', { items: [1,2,3] });res.cookie('cart', { items: [1,2,3] }, { maxAge: 900000 });
在使用Cookie解析器中間件時,此方法也支持簽名的Cookie。只需將包含signed
的選項設置為true
即可。然后將使用res.cookie()
傳遞給它的密碼cookieParser(secret)
來簽名。
res.cookie('name', 'tobi', { signed: true });
稍后,您可以通過req.signedCookie對象訪問此值。
通過name
清除指定的cookie 。有關該options
對象的詳細信息,請參閱res.cookie()。
Web瀏覽器和其他兼容的客戶端將只清除cookie,如果給定的options
是給res.cookie(),排除expires
和maxAge
。
res.cookie('name', 'tobi', { path: '/admin' });res.clearCookie('name', { path: '/admin' });
options
在Express v4.16.0及更高版本支持可選參數(shù)。
path
以“附件”的形式傳輸文件。通常,瀏覽器會提示用戶下載。默認情況下,Content-Disposition
頭文件“filename =”參數(shù)是path
(通常出現(xiàn)在瀏覽器對話框中)。用filename
參數(shù)覆蓋此默認值。
當發(fā)生錯誤或傳輸完成時,該方法會調用可選的回調函數(shù)fn
。此方法使用res.sendFile()傳輸文件。
可選options
參數(shù)傳遞給底層res.sendFile()調用,并使用完全相同的參數(shù)。
res.download('/report-12345.pdf'); res.download('/report-12345.pdf', 'report.pdf'); res.download('/report-12345.pdf', 'report.pdf', function(err){ if (err) { // Handle error, but keep in mind the response may be partially-sent // so check res.headersSent } else { // decrement a download credit, etc. }});
結束響應過程。這個方法實際上來自Node核心,特別是http.ServerResponse的response.end()方法。
用于快速結束沒有任何數(shù)據(jù)的響應。如果您需要使用數(shù)據(jù)進行響應,請使用res.send()和res.json()等方法。
res.end();res.status(404).end();
Accept
對請求對象上的HTTP標頭執(zhí)行內容協(xié)商(如果存在)。它使用req.accepts()根據(jù)按質量值排序的可接受類型為請求選擇處理程序。如果頭沒有指定,則調用第一個回調函數(shù)。當找不到匹配時,服務器回應406“不可接受”,或調用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() { // log the request and respond with 406 res.status(406).send('Not Acceptable'); }});
除了規(guī)范化的MIME類型之外,您還可以使用映射到這些類型的擴展名稱來實現(xiàn)稍微冗長的實現(xiàn):
res.format({ text: function(){ res.send('hey'); }, html: function(){ res.send('<p>hey</p>'); }, json: function(){ res.send({ message: 'hey' }); }});
返回由指定的HTTP響應頭field
。不區(qū)分大小寫。
res.get('Content-Type');// => "text/plain"
發(fā)送JSON響應。此方法使用JSON.stringify()將響應(使用正確的內容類型)作為參數(shù)轉換為JSON字符串。
該參數(shù)可以是任何JSON類型,包括對象,數(shù)組,字符串,布爾值或數(shù)字,您也可以使用它將其他值轉換為JSON,例如null
和undefined
(盡管這些在技術上無效JSON)。
res.json(null); res.json({ user: 'tobi' }); res.status(500).json({ error: 'message' });
使用JSONP支持發(fā)送JSON響應。res.json()
除了它選擇JSONP回調支持之外,此方法與之相同。
res.jsonp(null);// => callback(null) res.jsonp({ user: 'tobi' });// => callback({ "user": "tobi" })res.status(500).jsonp({ error: 'message' });// => callback({ "error": "message" })
默認情況下,JSONP回調名稱callback
很簡單。用jsonp回調名稱設置覆蓋它。
以下是使用相同代碼的JSONP響應的一些示例:
// ?callback=foores.jsonp({ user: 'tobi' }); // => foo({ "user": "tobi" }) app.set('jsonp callback name', 'cb'); // ?cb=foores.status(500).jsonp({ error: 'message' }); // => foo({ "error": "message" })
連接links
提供的參數(shù)屬性以填充響應的Link
HTTP標頭字段。
For example, the following call:
res.links({ next: 'http://api.example.com/users?page=2', last: 'http://api.example.com/users?page=5'});
產(chǎn)生以下結果:
Link: <http://api.example.com/users?page=2>; rel="next", <http://api.example.com/users?page=5>; rel="last"
將響應Location
HTTP標頭設置為指定的path
參數(shù)。
res.location('/foo/bar');res.location('http://example.com');res.location('back');
path
“后”的值具有特殊的含義,它指的是在指定的URL Referer
的請求的報頭中。如果Referer
未指定標題,則表示“/”。
對URL進行編碼后,如果尚未編碼,Express會將指定的URL傳遞到Location
標頭中的瀏覽器,而不進行任何驗證。
瀏覽器負責從當前URL或引用URL以及Location
頭中指定的URL中派生出預期的URL ; 并相應地重定向用戶。
重定向到從指定的URL派生的URL path
,帶有指定的status
,與HTTP狀態(tài)代碼對應的正整數(shù)。如果未指定,則status
默認為“找到”302。
res.redirect('/foo/bar');res.redirect('http://example.com');res.redirect(301, 'http://example.com');res.redirect('../login');
重定向可以是用于重定向到其他網(wǎng)站的完全限定的URL:
res.redirect('http://google.com');
重定向可以相對于主機名的根。例如,如果應用程序處于打開狀態(tài)http://example.com/admin/post/new
,則以下將重定向到URL http://example.com/admin
:
res.redirect('/admin');
重定向可以相對于當前的URL。例如,http://example.com/blog/admin/
(注意尾部斜線),以下內容將重定向到URL http://example.com/blog/admin/post/new
。
res.redirect('post/new');
重定向到post/new
的http://example.com/blog/admin
(沒有尾隨斜線),會重定向到http://example.com/blog/post/new
。
如果您發(fā)現(xiàn)上述行為令人困惑,請將路徑段視為目錄(尾隨斜杠)和文件,它將開始有意義。
路徑相對重定向也是可能的。如果你打開http://example.com/admin/post/new
,以下將重定向到http://example.com/admin/post
:
res.redirect('..');
back
重定向請求重定向回引薦,默認為/
引薦丟失時。
res.redirect('back');
渲染view
并將呈現(xiàn)的HTML字符串發(fā)送到客戶端。可選參數(shù):
locals
,其屬性定義視圖的局部變量的對象。
callback
,一個回調函數(shù)。如果提供,該方法返回可能的錯誤和呈現(xiàn)的字符串,但不執(zhí)行自動響應。發(fā)生錯誤時,該方法將在next(err)
內部調用。
view
參數(shù)是一個字符串,它是視圖文件來加載的文件路徑。這可以是絕對路徑,也可以是相對于views
設置的路徑。如果路徑不包含文件擴展名,則該view engine
設置將確定文件擴展名。如果路徑包含文件擴展名,則Express將加載指定模板引擎的模塊(通過require()
)并使用加載模塊的__express
函數(shù)來加載它。
有關更多信息,請參閱使用Express模板引擎。
注:view
參數(shù)執(zhí)行文件系統(tǒng)操作,比如從磁盤讀取文件和評估的Node.js模塊,并且因此出于安全考慮,不應該包含從最終用戶的輸入。
本地變量cache
啟用視圖緩存。將其設置為true
,在開發(fā)期間緩存視圖; 視圖緩存在生產(chǎn)中默認啟用。
// send the rendered view to the clientres.render('index');// if a callback is specified, the rendered HTML string has to be sent explicitly res.render('index', function(err, html) { res.send(html);});// pass a local variable to the viewres.render('user', { name: 'Tobi' }, function(err, html) { // ...});
發(fā)送HTTP響應。
body
參數(shù)可以是一個Buffer
對象,一個String
對象或一個Array
。例如:
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' });
此方法為簡單的非流式響應執(zhí)行許多有用的任務:例如,它會自動分配Content-Length
HTTP響應頭字段(除非先前已定義),并提供自動HEAD和HTTP緩存新鮮度支持。
當參數(shù)是一個Buffer
對象時,該方法將Content-Type
響應頭字段設置為“application / octet-stream”,除非先前定義如下所示:
res.set('Content-Type', 'text/html');res.send(new Buffer('<p>some html</p>'));
當參數(shù)是String
時,該方法設置Content-Type
為“text / html”:
res.send('<p>some html</p>');
當參數(shù)是Array
或者Object
時,Express以JSON表示響應:
res.send({ user: 'tobi' });res.send([1,2,3]);
res.sendFile()
由Express v4.8.0起支持。
在給定的位置path
傳輸文件。Content-Type
根據(jù)文件名的擴展名設置響應HTTP頭字段。除非root
在選項對象中設置選項,否則path
必須是該文件的絕對路徑。
下表提供了options
參數(shù)的詳細信息。
屬性 | 描述 | 默認 | 可用性 |
---|---|---|---|
MAXAGE | 以毫秒為單位設置Cache-Control標頭的max-age屬性,或以ms格式設置字符串 | 0 | |
root | 相對文件名的根目錄。 | ||
lastModified | 將Last-Modified標頭設置為OS上文件的最后修改日期。設置為false將其禁用。 | 啟用 | 4.9.0+ |
headers | 包含HTTP標頭的對象以與該文件一起提供。 | ||
dotfiles | 提供點文件的選項??赡艿闹凳恰霸试S”,“拒絕”,“忽略”。 | “忽視” | |
acceptRanges | 啟用或禁用接受范圍的請求。 | 真正 | 4.14+ |
CacheControl | 啟用或禁用設置緩存控制響應頭。 | 真正 | 4.14+ |
一成不變 | 在Cache-Control響應頭中啟用或禁用不可變指令。如果啟用,還應指定maxAge選項以啟用緩存。不可變的指令將阻止受支持的客戶端在maxAge選項生命期間發(fā)出條件請求,以檢查文件是否已更改。 | 假 | 4.16+ |
fn(err)
方法在傳輸完成或發(fā)生錯誤時調用回調函數(shù)。如果指定了回調函數(shù)并且發(fā)生錯誤,則回調函數(shù)必須通過結束請求 - 響應循環(huán)或將控制權交給下一個路徑來顯式處理響應過程。
這是一個使用res.sendFile
所有參數(shù)的例子。
app.get('/file/:name', function (req, res, next) { var options = { root: __dirname + '/public/', dotfiles: 'deny', headers: { 'x-timestamp': Date.now(), 'x-sent': true } }; var fileName = req.params.name; res.sendFile(fileName, options, function (err) { if (err) { next(err); } 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('/uploads/' + uid + '/' + file); } else { res.status(403).send("Sorry! You can't see that."); } });});
有關更多信息,或者如果您有問題或疑慮,請參閱send.
將響應HTTP狀態(tài)代碼設置為statusCode
并將其字符串表示形式作為響應主體發(fā)送。
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')
如果指定了不支持的狀態(tài)碼,則HTTP狀態(tài)仍然設置為statusCode
,并且代碼的字符串版本將作為響應主體發(fā)送。
res.sendStatus(2000); // equivalent to res.status(2000).send('2000')
將響應的HTTP標頭field
設置為value
。要一次設置多個字段,請傳遞一個對象作為參數(shù)。
res.set('Content-Type', 'text/plain'); res.set({ 'Content-Type': 'text/plain', 'Content-Length': '123', 'ETag': '12345'});
別名為res.header(field [, value])
。
設置響應的HTTP狀態(tài)。它是Node的response.statusCode的可鏈式別名。
res.status(403).end(); res.status(400).send('Bad Request'); res.status(404).sendFile('/absolute/path/to/404.png');
設置Content-Type
為通過確定HTTP標頭到MIME類型mime.lookup()為指定的type
。如果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:
如果該字段不存在Vary
,則將字段添加到響應標題中。
res.vary('User-Agent').render('docs');
router
對象是一個孤立的中間件和路由實例。您可以將其視為只能執(zhí)行中間件和路由功能的“小型應用程序”。每個Express應用程序都有一個內置的應用程序路由器。
路由器的行為就像中間件本身,因此您可以將其用作app.use()的參數(shù)或作為另一個路由器的use()方法的參數(shù)。
頂層express
對象有一個Router()創(chuàng)建新router
對象的方法。
一旦你創(chuàng)建了一個路由器的對象,你可以添加中間件和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) { // ..});
然后,您可以通過這種方式將路由器用于特定的根網(wǎng)址,將路線分隔為文件甚至迷你應用程序。
// only requests to /calendar/* will be sent to our "router" app.use('/calendar', router);
這個方法就像router.METHOD()
一樣,只是它匹配所有的HTTP方法(動詞)。
此方法對于為特定路徑前綴或任意匹配映射“全局”邏輯非常有用。例如,如果將以下路由放置在所有其他路由定義的頂部,則需要從該點開始的所有路由都需要身份驗證,并自動加載用戶。請記住,這些回調不必作為終點; loadUser
可以執(zhí)行任務,然后調用next()
繼續(xù)匹配后續(xù)路由。
router.all('*', requireAuthentication, loadUser);
或者相當于:
router.all('*', requireAuthentication)router.all('*', loadUser);
Another example of this is white-listed “global” functionality. Here the example is much like before, but it only restricts paths prefixed with “/api”:
router.all('/api/*', requireAuthentication);
這些router.METHOD()
方法在Express中提供了路由功能,其中METHOD是小寫的HTTP方法之一,如GET,PUT,POST等。因此,實際的方法是router.get()
,router.post()
,router.put()
等。
除了方法之外,如果以前沒有為路徑router.get()
調用函數(shù)GETrouter.head()
,則會自動為HTTP HEAD
方法調用router.get()
函數(shù)。
您可以提供多個回調,并且所有處理都是平等對待的,并且行為與中間件一樣,只是這些回調可能會調用next('route')
繞過剩余的路由回調。您可以使用此機制在路線上執(zhí)行前提條件,然后在沒有理由繼續(xù)匹配路線時將控制權傳遞給后續(xù)路線。
以下片段說明了可能的最簡單的路由定義。Express將路徑字符串轉換為正則表達式,用于在內部匹配傳入的請求。在執(zhí)行這些匹配時,不會考慮查詢字符串,例如“GET /”將與以下路由匹配,就像“GET /?name = tobi”一樣。
router.get('/', function(req, res){ res.send('hello world');});
您也可以使用正則表達式 - 如果您有非常特定的約束條件,則很有用,例如,以下內容將與“GET / commits / 71dbb9c”以及“GET /commits/71dbb9c..4c084f9”匹配。
router.get(/^\/commits\/(\w+)(?:\.\.(\w+))?$/, function(req, res){ var from = req.params[0]; var to = req.params[1] || 'HEAD'; res.send('commit range ' + from + '..' + to);});
添加回調觸發(fā)器來設置路由參數(shù),其中name
是參數(shù)的名稱并且callback
是回調函數(shù)。盡管name
在技術上是可選的,但使用這種沒有它的方法已經(jīng)被棄用,從Express v4.11.0開始(見下文)。
回調函數(shù)的參數(shù)是:
req
,請求對象。
res
,響應對象。
next
,表示下一個中間件功能。
name
參數(shù)的值。
參數(shù)的名稱。
與app.param()
不同,router.param()
不接受一組路由參數(shù)。
例如,當:user
存在于路徑路徑中時,您可以映射用戶加載邏輯以自動提供給req.user
路徑,或對參數(shù)輸入執(zhí)行驗證。
router.param('user', function(req, res, next, id) { // try to get the user details from the User model and attach it to the request object User.find(id, function(err, user) { if (err) { next(err); } else if (user) { req.user = user; next(); } else { next(new Error('failed to load user')); } });});
Param回調函數(shù)在它們被定義的路由器的本地。它們不會被安裝的應用程序或路由器繼承。因此,定義的參數(shù)回調router
將僅由路由上定義的路由參數(shù)觸發(fā)router
。
即使參數(shù)在多個路由中匹配,參數(shù)回調也只會在請求 - 響應周期中調用一次,如以下示例所示。
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 matches 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)
方法的行為可以完全通過只傳遞一個函數(shù)來改變router.param()
。這個函數(shù)是一個自定義實現(xiàn)router.param(name, callback)
該如何行為- 它接受兩個參數(shù)并且必須返回一個中間件。
此函數(shù)的第一個參數(shù)是應該捕獲的URL參數(shù)的名稱,第二個參數(shù)可以是可用于返回中間件實現(xiàn)的任何JavaScript對象。
該函數(shù)返回的中間件決定捕獲URL參數(shù)時發(fā)生的行為。
在這個例子中,router.param(name, callback)
簽名被修改為router.param(name, accessId)
。router.param()
現(xiàn)在接受一個名字和一個數(shù)字,而不是接受一個名字和一個回叫。
var express = require('express'); var app = express(); var router = express.Router(); // customizing the behavior of router.param() router.param(function(param, option) { return function (req, res, next, val) { if (val == option) { next(); } else { res.sendStatus(403); } }}); // using the customized router.param() router.param('id', 1337); // route to trigger the capture router.get('/user/:id', function (req, res) { res.send('OK');}); app.use(router); app.listen(3000, function () { console.log('Ready');} );
在此示例中,router.param(name, callback)
簽名保持不變,但不是中間件回調,而是定義了自定義數(shù)據(jù)類型檢查函數(shù)來驗證用戶標識的數(shù)據(jù)類型。
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);});
返回單個路由的實例,然后您可以使用該實例來處理具有可選中間件的HTTP指令。使用router.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'));});
此方法重新使用單個/users/:user_id
路徑并為各種HTTP方法添加處理程序。
注意:在使用時router.route()
,中間件排序基于創(chuàng)建路由的時間,而不是處理程序添加到路由時的時間。為此,您可以考慮處理程序屬于它們添加到的路線方法。
使用指定的中間件功能或可選的裝載路徑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 middlewarerouter.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 from the mount pointrouter.use('/bar', function(req, res, next) { // ... maybe some additional /bar logging ... next();});// always invokedrouter.use(function(req, res, next) { res.send('Hello World');});app.use('/foo', router);app.listen(3000);
“裝載”路徑被剝離并且對中間件功能不可見。此功能的主要作用是安裝的中間件功能可以在無需更改代碼的情況下運行,而不管其“前綴”路徑名。
您使用router.use()
定義中間件的順序非常重要。它們是按順序調用的,因此順序定義了中間件的優(yōu)先級。例如,通常記錄器是您要使用的第一個中間件,這樣每個請求都會被記錄下來。
var logger = require('morgan');router.use(logger()); router.use(express.static(__dirname + '/public')); router.use(function(req, res){ res.send('Hello');});
現(xiàn)在假設您想忽略對靜態(tài)文件的記錄請求,但要繼續(xù)記錄之后定義的路由和中間件logger()
。在添加記錄器中間件之前,您只需將呼叫express.static()
移至頂端即可:
router.use(express.static(__dirname + '/public')); router.use(logger()); router.use(function(req, res){ res.send('Hello');});
另一個例子是提供來自多個目錄的文件,優(yōu)先于其他文件的“./public”:
app.use(express.static(__dirname + '/public')); app.use(express.static(__dirname + '/files')); app.use(express.static(__dirname + '/uploads'));
router.use()
方法還支持命名參數(shù),以便其他路由器的安裝點可以使用命名參數(shù)進行預加載。
注意:雖然這些中間件功能是通過特定路由器添加的,但它們運行時由其所連接的路徑(而不是路由器)定義。因此,如果路由匹配,通過一臺路由器添加的中間件可能會為其他路由器運行。例如,此代碼顯示了在同一路徑上安裝的兩個不同的路由器:
var authRouter = express.Router(); var openRouter = express.Router(); authRouter.use(require('./authenticate').basic(usersdb)); authRouter.get('/:user_id/edit', function(req, res, next) { // ... Edit user UI ... });openRouter.get('/', function(req, res, next) { // ... List users ... })openRouter.get('/:user_id', function(req, res, next) { // ... View user ... })app.use('/users', authRouter);app.use('/users', openRouter);
即使身份驗證中間件是通過authRouter
它添加的,它也會在由該openRouter
路由器安裝的路由器上定義的路由上運行/users
。為了避免這種情況,請為每個路由器使用不同的路徑。