Express 是一個路由和中介軟體網路架構,本身的功能極少:Express 應用程式基本上是一系列中介軟體函式呼叫。
中介軟體函式是可以存取 要求物件 (req
)、回應物件 (res
) 以及應用程式要求回應週期中下一個中介軟體函式的函式。下一個中介軟體函式通常以名為 next
的變數表示。
中介軟體函式可以執行下列工作
如果目前的 middleware 函式未結束請求-回應週期,它必須呼叫 next()
以將控制權傳遞給下一個 middleware 函式。否則,請求將會掛起。
Express 應用程式可以使用下列類型的 middleware
您可以載入具有選用掛載路徑的應用程式層級和路由器層級 middleware。您也可以同時載入一系列 middleware 函式,這會在掛載點建立 middleware 系統的子堆疊。
使用 app.use()
和 app.METHOD()
函式將應用程式層級 middleware 繫結到 app 物件 的執行個體,其中 METHOD
是 middleware 函式處理的請求的 HTTP 方法(例如 GET、PUT 或 POST),以小寫表示。
此範例顯示沒有掛載路徑的 middleware 函式。當應用程式收到請求時,每次都會執行此函式。
const express = require('express')
const app = express()
app.use((req, res, next) => {
console.log('Time:', Date.now())
next()
})
此範例顯示掛載在 /user/:id
路徑上的 middleware 函式。此函式會在 /user/:id
路徑上針對任何類型的 HTTP 請求執行。
app.use('/user/:id', (req, res, next) => {
console.log('Request Type:', req.method)
next()
})
此範例顯示路由及其處理函式(middleware 系統)。此函式會處理對 /user/:id
路徑的 GET 請求。
app.get('/user/:id', (req, res, next) => {
res.send('USER')
})
以下是載入一系列 middleware 函式到具有掛載路徑的掛載點的範例。它說明了 middleware 子堆疊,會針對對 /user/:id
路徑的任何類型的 HTTP 請求列印請求資訊。
app.use('/user/:id', (req, res, next) => {
console.log('Request URL:', req.originalUrl)
next()
}, (req, res, next) => {
console.log('Request Type:', req.method)
next()
})
路由處理函式讓您能夠為路徑定義多個路由。下方的範例為對 /user/:id
路徑的 GET 請求定義兩個路由。第二個路由不會造成任何問題,但它永遠不會被呼叫,因為第一個路由會結束請求-回應週期。
此範例顯示處理對 /user/:id
路徑的 GET 請求的 middleware 子堆疊。
app.get('/user/:id', (req, res, next) => {
console.log('ID:', req.params.id)
next()
}, (req, res, next) => {
res.send('User Info')
})
// handler for the /user/:id path, which prints the user ID
app.get('/user/:id', (req, res, next) => {
res.send(req.params.id)
})
若要略過路由器中介軟體堆疊中其餘的中介軟體函式,請呼叫 next('route')
將控制權傳遞至下一個路由。注意:next('route')
僅會在使用 app.METHOD()
或 router.METHOD()
函式載入的中介軟體函式中運作。
此範例顯示處理對 /user/:id
路徑的 GET 請求的 middleware 子堆疊。
app.get('/user/:id', (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()
}, (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', (req, res, next) => {
res.send('special')
})
中介軟體也可以宣告在陣列中,以利重複使用。
這個範例顯示一個陣列,其中包含一個中介軟體子堆疊,用於處理對 /user/:id
路徑的 GET 要求
function logOriginalUrl (req, res, next) {
console.log('Request URL:', req.originalUrl)
next()
}
function logMethod (req, res, next) {
console.log('Request Type:', req.method)
next()
}
const logStuff = [logOriginalUrl, logMethod]
app.get('/user/:id', logStuff, (req, res, next) => {
res.send('User Info')
})
路由層級中介軟體的運作方式與應用程式層級中介軟體相同,但它會繫結至 express.Router()
的執行個體。
const router = express.Router()
使用 router.use()
和 router.METHOD()
函式載入路由層級中介軟體。
下列範例程式碼使用路由層級中介軟體,複製上方顯示的應用程式層級中介軟體系統
const express = require('express')
const app = express()
const router = express.Router()
// a middleware function with no mount path. This code is executed for every request to the router
router.use((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', (req, res, next) => {
console.log('Request URL:', req.originalUrl)
next()
}, (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', (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()
}, (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', (req, res, next) => {
console.log(req.params.id)
res.render('special')
})
// mount the router on the app
app.use('/', router)
若要略過路由器的其餘中介軟體函式,請呼叫 next('router')
將控制權傳遞回路由器執行個體。
此範例顯示處理對 /user/:id
路徑的 GET 請求的 middleware 子堆疊。
const express = require('express')
const app = express()
const router = express.Router()
// predicate the router with a check and bail out when needed
router.use((req, res, next) => {
if (!req.headers['x-auth']) return next('router')
next()
})
router.get('/user/:id', (req, res) => {
res.send('hello, user!')
})
// use the router and 401 anything falling through
app.use('/admin', router, (req, res) => {
res.sendStatus(401)
})
錯誤處理中介軟體總是需要 四個 參數。您必須提供四個參數,才能將其識別為錯誤處理中介軟體函式。即使您不需要使用 next
物件,您也必須指定它,以維持簽章。否則,next
物件會被解釋為一般中介軟體,且無法處理錯誤。
定義錯誤處理中介軟體函式的步驟與其他中介軟體函式相同,但參數有四個而不是三個,特別是簽章為 (err, req, res, next)
)
app.use((err, req, res, next) => {
console.error(err.stack)
res.status(500).send('Something broke!')
})
有關錯誤處理中介軟體的詳細資訊,請參閱:錯誤處理。
從 4.x 版開始,Express 不再依賴 Connect。先前包含在 Express 中的中介軟體函式現在位於獨立的模組中;請參閱 中介軟體函式清單。
Express 具有下列內建中介軟體函式
使用第三方中間件來為 Express 應用程式新增功能。
安裝 Node.js 模組以取得所需的功,然後在應用程式層級或路由器層級載入應用程式。
以下範例說明如何安裝和載入 cookie 剖析中間件函式 cookie-parser
。
$ npm install cookie-parser
const express = require('express')
const app = express()
const cookieParser = require('cookie-parser')
// load the cookie-parsing middleware
app.use(cookieParser())
如需一般與 Express 搭配使用的第三方中間件函式部分清單,請參閱:第三方中間件。