主题
中间件
中间件是形如 (req, res, next) 的函数,按注册顺序处理请求。它可以读取或修改 req、res,结束响应,或调用 next() 继续请求链。
分类与位置
| 类型 | 注册方式 | 常见用途 |
|---|---|---|
| 应用级 | app.use()、app.METHOD() | 日志、解析请求体、鉴权。 |
| 路由级 | router.use()、router.METHOD() | 某个业务模块的权限和参数校验。 |
| 内置 | express.json()、express.static() | JSON、表单、静态文件。 |
| 第三方 | cors、multer 等 | CORS、文件上传等扩展能力。 |
| 错误处理 | (err, req, res, next) | 统一转换和记录异常。 |
基本规则
- 未发送响应时必须调用
next(),否则请求会挂起。 req、res在同一请求链中共享;扩展属性时应使用语义明确的名称。- 错误处理中间件拥有四个参数,并且注册在全部普通路由之后。
- 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: '接口不存在' })
})