?
本文檔使用 php中文網(wǎng)手冊(cè) 發(fā)布
中間件功能是可以訪問請(qǐng)求對(duì)象(req
),響應(yīng)對(duì)象(res
)以及next
應(yīng)用程序請(qǐng)求 - 響應(yīng)周期中的函數(shù)。該next
功能是Express路由器中的一項(xiàng)功能,當(dāng)被調(diào)用時(shí),該功能執(zhí)行當(dāng)前中間件之后的中間件。
中間件功能可以執(zhí)行以下任務(wù):
執(zhí)行任何代碼。
對(duì)請(qǐng)求和響應(yīng)對(duì)象進(jìn)行更改。
結(jié)束請(qǐng)求 - 響應(yīng)循環(huán)。
調(diào)用堆棧中的下一個(gè)中間件。
如果當(dāng)前的中間件功能沒有結(jié)束請(qǐng)求 - 響應(yīng)周期,則它必須調(diào)用next()
以將控制傳遞給下一個(gè)中間件功能。否則,請(qǐng)求將被掛起。
下圖顯示了中間件函數(shù)調(diào)用的元素:
適用中間件功能的HTTP方法。中間件功能適用的路徑(路由)。中間件功能。中間件功能的回調(diào)參數(shù),按照慣例稱為“下一個(gè)”。對(duì)中間件功能的HTTP響應(yīng)參數(shù),按照慣例稱為“res”。中間件功能的HTTP請(qǐng)求參數(shù),按慣例稱為“req”。 |
---|
這是一個(gè)簡(jiǎn)單的“Hello World”表達(dá)應(yīng)用程序的例子。本文的其余部分將定義并向應(yīng)用程序添加兩個(gè)中間件功能:一個(gè)調(diào)用myLogger
打印簡(jiǎn)單的日志消息,另一個(gè)調(diào)用requestTime
顯示HTTP請(qǐng)求的時(shí)間戳。
var express = require('express')var app = express()app.get('/', function (req, res) { res.send('Hello World!')})app.listen(3000)
這是一個(gè)稱為“myLogger”的中間件功能的簡(jiǎn)單示例。這個(gè)函數(shù)只是在對(duì)應(yīng)用程序的請(qǐng)求通過時(shí)打印“LOGGED”。中間件功能被分配給一個(gè)名為的變量myLogger
。
var myLogger = function (req, res, next) { console.log('LOGGED') next()}
注意上面的呼叫next()
。調(diào)用這個(gè)函數(shù)會(huì)調(diào)用應(yīng)用程序中的下一個(gè)中間件功能。該next()
函數(shù)不是Node.js或Express API的一部分,而是傳遞給中間件功能的第三個(gè)參數(shù)。該next()
函數(shù)可以被命名為任何東西,但按照慣例,它總是被命名為“下一個(gè)”。為避免混淆,請(qǐng)始終使用此約定。
要加載中間件功能,請(qǐng)調(diào)用app.use()
,指定中間件功能。例如,以下代碼會(huì)在myLogger
到根路徑(/)的路由之前加載中間件功能。
var express = require('express')var app = express()var myLogger = function (req, res, next) { console.log('LOGGED') next()}app.use(myLogger)app.get('/', function (req, res) { res.send('Hello World!')})app.listen(3000)
每次應(yīng)用收到請(qǐng)求時(shí),它都會(huì)向終端輸出“LOGGED”消息。
中間件加載順序非常重要:首先加載的中間件功能也首先執(zhí)行。
如果myLogger
在到根路徑的路由之后加載,請(qǐng)求將永遠(yuǎn)達(dá)不到它,并且應(yīng)用程序不會(huì)打印“LOGGED”,因?yàn)楦窂降穆酚商幚沓绦驎?huì)終止請(qǐng)求 - 響應(yīng)循環(huán)。
中間件功能myLogger
僅打印消息,然后通過調(diào)用該next()
函數(shù)將請(qǐng)求傳遞到堆棧中的下一個(gè)中間件功能。
接下來,我們將創(chuàng)建一個(gè)名為“requestTime”的中間件函數(shù),并將其添加為調(diào)用requestTime
請(qǐng)求對(duì)象的屬性。
var requestTime = function (req, res, next) { req.requestTime = Date.now() next()}
應(yīng)用程序現(xiàn)在使用requestTime
中間件功能。此外,根路徑路由的回調(diào)函數(shù)使用中間件功能添加到的屬性req
(請(qǐng)求對(duì)象)。
var express = require('express')var app = express()var requestTime = function (req, res, next) { req.requestTime = Date.now() next()}app.use(requestTime)app.get('/', function (req, res) { var responseText = 'Hello World!<br>' responseText += '<small>Requested at: ' + req.requestTime + '</small>' res.send(responseText)})app.listen(3000)
當(dāng)您向應(yīng)用程序的根目錄發(fā)出請(qǐng)求時(shí),應(yīng)用程序現(xiàn)在會(huì)在瀏覽器中顯示請(qǐng)求的時(shí)間戳。
因?yàn)槟梢栽L問請(qǐng)求對(duì)象,響應(yīng)對(duì)象,堆棧中的下一個(gè)中間件功能以及整個(gè)Node.js API,所以使用中間件功能的可能性是無限的。
有關(guān)Express中間件的更多信息,請(qǐng)參閱:使用Express中間件。
如果您需要中間件可配置,則導(dǎo)出一個(gè)接受選項(xiàng)對(duì)象或其他參數(shù)的函數(shù),然后根據(jù)輸入?yún)?shù)返回中間件實(shí)現(xiàn)。
File: my-middleware.js
module.exports = function(options) { return function(req, res, next) { // Implement the middleware function based on the options object next() } }
現(xiàn)在可以使用中間件,如下所示。
var mw = require('./my-middleware.js')app.use(mw({ option1: '1', option2: '2' }))