使用中介軟體
Express是一個路由和中介軟體Web框架,其本身的功能非常小:Express應用程式本質上是一系列中介軟體函式呼叫。
中介軟體函式是可以訪問請求物件(req
)、響應物件(res
)以及應用程式請求—響應週期中的下一個中介軟體函式的函式,下一個中介軟體函式通常由名為next
的變數表示。
中介軟體函式可以執行以下任務:
- 執行任何程式碼。
- 更改請求和響應物件。
- 結束請求—響應週期。
- 呼叫堆疊中的下一個中介軟體函式。
如果當前的中介軟體函式沒有結束請求—響應週期,它必須呼叫next()
將控制權傳遞給下一個中介軟體函式,否則,請求將被掛起。
Express應用程式可以使用以下型別的中介軟體:
- 應用程式級中介軟體
- 路由器級中介軟體
- 錯誤處理中介軟體
- 內建中介軟體
- 第三方中介軟體
你可以使用可選的裝載路徑載入應用程式級和路由器級中介軟體,你還可以將一系列中介軟體函式載入在一起,從而在裝載點建立中介軟體系統的子堆疊。
應用程式級中介軟體
使用app.use()
和app.METHOD()
函式將應用程式級中介軟體繫結到app
物件的例項,其中METHOD
是中介軟體函式處理的請求的小寫HTTP方法(例如GET,PUT或POST)。
此示例顯示了沒有裝載路徑的中介軟體函式,每次應用程式收到請求時都會執行該函式。
var app = express()
app.use(function (req, res, next) {
console.log(`Time:`, Date.now())
next()
})
此示例顯示了安裝在/user/:id
路徑上的中介軟體函式,對/user/:id
路徑上的任何型別的HTTP請求執行該函式。
app.use(`/user/:id`, function (req, res, next) {
console.log(`Request Type:`, req.method)
next()
})
此示例顯示了路由及其處理函式(中介軟體系統),該函式處理對/user/:id
路徑的GET請求。
app.get(`/user/:id`, function (req, res, next) {
res.send(`USER`)
})
下面是一個使用掛載路徑在掛載點載入一系列中介軟體函式的示例,它說明了一箇中介軟體子堆疊,它將任何型別的HTTP請求的請求資訊列印到/user/:id
路徑。
app.use(`/user/:id`, function (req, res, next) {
console.log(`Request URL:`, req.originalUrl)
next()
}, function (req, res, next) {
console.log(`Request Type:`, req.method)
next()
})
路由處理程式使你可以為路徑定義多個路由,下面的示例為/user/:id
路徑定義了兩個GET請求路由,第二個路由不會引起任何問題,但它永遠不會被呼叫,因為第一個路由結束了請求—響應週期。
此示例顯示了一箇中介軟體子堆疊,它處理對/user/:id
路徑的GET請求。
app.get(`/user/:id`, function (req, res, next) {
console.log(`ID:`, req.params.id)
next()
}, function (req, res, next) {
res.send(`User Info`)
})
// handler for the /user/:id path, which prints the user ID
app.get(`/user/:id`, function (req, res, next) {
res.end(req.params.id)
})
要從路由器中介軟體堆疊跳過其餘的中介軟體函式,請呼叫next(`route`)
將控制權傳遞給下一個路由,注意:next(`route`)
僅適用於使用app.METHOD()
或router.METHOD()
函式載入的中介軟體函式。
此示例顯示了一箇中介軟體子堆疊,它處理對/user/:id
路徑的GET請求。
app.get(`/user/:id`, function (req, res, next) {
// if the user ID is 0, skip to the next route
if (req.params.id === `0`) next(`route`)
// otherwise pass the control to the next middleware function in this stack
else next()
}, function (req, res, next) {
// send a regular response
res.send(`regular`)
})
// handler for the /user/:id path, which sends a special response
app.get(`/user/:id`, function (req, res, next) {
res.send(`special`)
})
路由器級中介軟體
路由器級中介軟體的工作方式與應用程式級中介軟體的工作方式相同,只是它繫結到express.Router()
的例項。
var router = express.Router()
使用router.use()
和router.METHOD()
函式載入路由器級中介軟體。
以下示例程式碼通過使用路由器級中介軟體複製上面顯示的應用程式級中介軟體的中介軟體系統:
var app = express()
var router = express.Router()
// a middleware function with no mount path. This code is executed for every request to the router
router.use(function (req, res, next) {
console.log(`Time:`, Date.now())
next()
})
// a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
router.use(`/user/:id`, function (req, res, next) {
console.log(`Request URL:`, req.originalUrl)
next()
}, function (req, res, next) {
console.log(`Request Type:`, req.method)
next()
})
// a middleware sub-stack that handles GET requests to the /user/:id path
router.get(`/user/:id`, function (req, res, next) {
// if the user ID is 0, skip to the next router
if (req.params.id === `0`) next(`route`)
// otherwise pass control to the next middleware function in this stack
else next()
}, function (req, res, next) {
// render a regular page
res.render(`regular`)
})
// handler for the /user/:id path, which renders a special page
router.get(`/user/:id`, function (req, res, next) {
console.log(req.params.id)
res.render(`special`)
})
// mount the router on the app
app.use(`/`, router)
要跳過其餘路由器中介軟體函式,請呼叫next(`router`)
將控制權交還出路由器例項。
此示例顯示了一箇中介軟體子堆疊,它處理對/admin
路徑的GET請求。
var app = express()
var router = express.Router()
// predicate the router with a check and bail out when needed
router.use(function (req, res, next) {
if (!req.headers[`x-auth`]) return next(`router`)
next()
})
router.get(`/`, function (req, res) {
res.send(`hello, user!`)
})
// use the router and 401 anything falling through
app.use(`/admin`, router, function (req, res) {
res.sendStatus(401)
})
錯誤處理中介軟體
錯誤處理中介軟體總是需要四個引數,你必須提供四個引數以將其標識為錯誤處理中介軟體函式,即使你不需要使用
next
物件,也必須指定它以維護簽名,否則,next
物件將被解釋為常規中介軟體,並且將無法處理錯誤。
以與其他中介軟體函式相同的方式定義錯誤處理中介軟體函式,除了四個引數而不是三個,特別是簽名(err, req, res, next)
:
app.use(function (err, req, res, next) {
console.error(err.stack)
res.status(500).send(`Something broke!`)
})
有關錯誤處理中介軟體的詳細資訊,請參閱:錯誤處理。
內建中介軟體
從版本4.x開始,Express不再依賴於Connect,之前包含在Express中的中介軟體函式現在位於不同的模組中,檢視中介軟體函式列表。
Express具有以下內建中介軟體函式:
-
express.static
提供靜態資源,如HTML檔案、影像等。 -
express.json
使用JSON的有效負載解析傳入的請求,注意:適用於Express 4.16.0+。 -
express.urlencoded
使用URL編碼的有效負載解析傳入的請求,注意:適用於Express 4.16.0+。
第三方中介軟體
使用第三方中介軟體為Express應用程式新增功能。
安裝Node.js模組以獲得所需的功能,然後在應用程式級別或路由器級別將其載入到你的應用程式中。
以下示例說明了安裝和載入cookie解析中介軟體函式cookie-parser
。
$ npm install cookie-parser
var express = require(`express`)
var app = express()
var cookieParser = require(`cookie-parser`)
// load the cookie-parsing middleware
app.use(cookieParser())
有關Express常用的第三方中介軟體函式的部分列表,請參閱:第三方中介軟體。