這個翻譯StrongLoop / IBM提供.

相對於英文版說明文件,本文件可能已不合時宜。如需最新的更新,請參閱英文版說明文件

使用中介軟體

Express 是一個本身功能極簡的路由與中介軟體 Web 架構:本質上,Express 應用程式是一系列的中介軟體函數呼叫。

中介軟體函數是一些有權存取要求物件 (req)、回應物件 (res) 和應用程式要求/回應循環中之下一個中介軟體函數的函數。下一個中介軟體函數通常以名為 next 的變數表示。

中介軟體函數可以執行下列作業:

如果現行中介軟體函數不會結束要求/回應循環,它必須呼叫 next(),以便將控制權傳遞給下一個中介軟體函數。否則,要求將會停擺。

Express 應用程式可以使用下列類型的中介軟體:

您可以使用選用的裝載路徑,來載入應用程式層次的中介軟體和路由器層次的中介軟體。您也可以一併載入一系列的中介軟體函數,如此會在裝載點建立一個中介軟體系統子堆疊。

應用程式層次的中介軟體

使用 app.use()app.METHOD() 函數,將應用程式層次的中介軟體連結至 app object 實例,其中 METHOD 是中介軟體函數要處理的 HTTP 要求方法(例如 GET、PUT 或 POST),並採小寫。

本例顯示沒有裝載路徑的中介軟體函數。每當應用程式收到要求時,就會執行此函數。

const app = express()

app.use((req, res, next) => {
  console.log('Time:', Date.now())
  next()
})

本例顯示裝載在 /user/:id 路徑的中介軟體函數。會對 /user/:id 路徑上任何類型的 HTTP 要求,執行此函數。

app.use('/user/:id', (req, res, next) => {
  console.log('Request Type:', req.method)
  next()
})

本例顯示路由和其處理程式函數(中介軟體系統)。此函數會處理指向 /user/:id 路徑的 GET 要求。

app.get('/user/:id', (req, res, next) => {
  res.send('USER')
})

下列範例顯示使用裝載路徑在裝載點載入一系列中介軟體函數。其中說明中介軟體子堆疊,這個子堆疊會針對指向 /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 要求。

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.end(req.params.id)
})

如果要跳過路由器中介軟體堆疊中其餘的中介軟體函數,請呼叫 next('route'),將控制權傳遞給下一個路由。附註next('route') 只適用於使用 app.METHOD()router.METHOD() 函數載入的中介軟體函數。

本例顯示中介軟體子堆疊,它處理了指向 /user/:id 路徑的 GET 要求。

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) => {
  // render a regular page
  res.render('regular')
})

// handler for the /user/:id path, which renders a special page
app.get('/user/:id', (req, res, next) => {
  res.render('special')
})

路由器層次的中介軟體

路由器層次的中介軟體的運作方式如同應用程式層次的中介軟體,不同之處在於它會連結至 express.Router() 實例。

const router = express.Router()

請利用 router.use()router.METHOD() 函數來載入路由器層次的中介軟體。

下列的程式碼範例是使用路由器層次的中介軟體,抄寫上述針對應用程式層次的中介軟體顯示的中介軟體系統:

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 物件也必須指定,以維護簽章。否則,會將 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.static,Express 先前隨附的所有中介軟體函數現在位於個別的模組中。請檢視中介軟體函數清單

express.static(root, [options])

Express 唯一的內建中介軟體函數是 express.static。此函數以 serve-static 為基礎,負責在 Express 應用程式中提供靜態資產。

root 引數指定提供靜態資產的根目錄。

options 選用物件可具有下列內容:

內容 說明 類型 預設值
dotfiles 用來提供點檔案的選項。可能的值是 “allow”、”deny” 和 “ignore” 字串 “ignore”
etag 啟用或停用 etag 的產生 布林 true
extensions 設定副檔名遞補。 陣列 []
index 傳送目錄索引檔。設定 false,會停用目錄檢索。 混合 “index.html”
lastModified Last-Modified 標頭設為作業系統上檔案的前次修改日期。可能的值是 truefalse 布林 true
maxAge 設定 Cache-Control 標頭的 max-age 內容,以毫秒為單位或 ms 格式的字串 數字 0
redirect 當路徑名稱是目錄時,重新導向至尾端 “/”。 布林 true
setHeaders 用來設定 HTTP 標頭以提供檔案的函數。 函數  

下列範例顯示如何使用 express.static 中介軟體函數,且其中詳細闡述了 options 物件:

const 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))

每一個應用程式可有多個靜態目錄:

app.use(express.static('public'))
app.use(express.static('uploads'))
app.use(express.static('files'))

如需 serve-static 函數和其選項的詳細資料,請參閱 serve-static 說明文件。

協力廠商中介軟體

使用協力廠商中介軟體,在 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 中常用的部分協力廠商中介軟體函數清單,請參閱:協力廠商中介軟體