Express 文檔(使用中間件)

使用中間件

Express是一個路由和中間件Web框架,其自己的功能很是小:Express應用程序本質上是一系列中間件函數調用。git

中間件函數是能夠訪問請求對象(req)、響應對象(res)以及應用程序請求—響應週期中的下一個中間件函數的函數,下一個中間件函數一般由名爲next的變量表示。github

中間件函數能夠執行如下任務:express

  • 執行任何代碼。
  • 更改請求和響應對象。
  • 結束請求—響應週期。
  • 調用堆棧中的下一個中間件函數。

若是當前的中間件函數沒有結束請求—響應週期,它必須調用next()將控制權傳遞給下一個中間件函數,不然,請求將被掛起。npm

Express應用程序可使用如下類型的中間件:json

  • 應用程序級中間件
  • 路由器級中間件
  • 錯誤處理中間件
  • 內置中間件
  • 第三方中間件

你可使用可選的裝載路徑加載應用程序級和路由器級中間件,你還能夠將一系列中間件函數加載在一塊兒,從而在裝載點建立中間件系統的子堆棧。segmentfault

應用程序級中間件

使用app.use()app.METHOD()函數將應用程序級中間件綁定到app對象的實例,其中METHOD是中間件函數處理的請求的小寫HTTP方法(例如GET,PUT或POST)。cookie

此示例顯示了沒有裝載路徑的中間件函數,每次應用程序收到請求時都會執行該函數。app

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經常使用的第三方中間件函數的部分列表,請參閱:第三方中間件。


上一篇:編寫中間件

下一篇:使用模板引擎

相關文章
相關標籤/搜索