Skip to content

中间件

中间件是形如 (req, res, next) 的函数,按注册顺序处理请求。它可以读取或修改 reqres,结束响应,或调用 next() 继续请求链。

分类与位置

类型注册方式常见用途
应用级app.use()app.METHOD()日志、解析请求体、鉴权。
路由级router.use()router.METHOD()某个业务模块的权限和参数校验。
内置express.json()express.static()JSON、表单、静态文件。
第三方corsmulterCORS、文件上传等扩展能力。
错误处理(err, req, res, next)统一转换和记录异常。

基本规则

  • 未发送响应时必须调用 next(),否则请求会挂起。
  • reqres 在同一请求链中共享;扩展属性时应使用语义明确的名称。
  • 错误处理中间件拥有四个参数,并且注册在全部普通路由之后。
  • Express 5 中,异步处理函数抛出异常或返回被拒绝的 Promise 会自动传递给错误处理中间件。

自定义中间件

js
function requestLogger(req, res, next) {
  const startedAt = Date.now()

  res.on('finish', () => {
    console.log(`${req.method} ${req.originalUrl} ${res.statusCode} ${Date.now() - startedAt}ms`)
  })

  next()
}

app.use(requestLogger)

错误处理

错误响应不应泄露堆栈、数据库错误或密钥等内部信息。已发送响应时,交由 Express 默认错误处理器继续处理。

js
app.get('/users/:id', async (req, res) => {
  const user = await findUser(req.params.id)

  if (!user) {
    const error = new Error('用户不存在')
    error.status = 404
    throw error
  }

  res.json(user)
})

app.use((err, req, res, next) => {
  if (res.headersSent) {
    return next(err)
  }

  const status = Number.isInteger(err.status) ? err.status : 500
  res.status(status).json({ message: status < 500 ? err.message : '服务器内部错误' })
})

404 处理

404 不是异常;它表示没有匹配到任何路由。因此应使用普通中间件,并放在路由之后、错误处理中间件之前。

js
app.use((req, res) => {
  res.status(404).json({ message: '接口不存在' })
})

基于 MIT 许可发布