外观
中间件是什么?
中间件是一串处理请求的函数。每个函数可以改请求、改响应、结束响应,或把控制权交给下一个。封装时保持「做一件事,要么调用 next,要么结束响应」。
原理
Express 和 Koa 的形状不同,但顺序一样:先注册的先进入。共用的日志、解析 JSON、鉴权放在路由前面。某个路由专有的检查放在那个路由上。
js
function auth(req, res, next) {
if (!req.headers.authorization) {
res.status(401).end()
return
}
next()
}错误处理是四个参数的函数,或者 Koa 里包在 try/catch 和 await next() 外面。普通中间件的错误要传给 next(err),否则请求会挂住。
不要在中间件里既写业务、又假设自己是链上的最后一个。数据库查询可以是单独的服务函数,中间件只负责把结果放进上下文或直接拒绝。
异步中间件必须返回 Promise 或使用框架支持的 async 函数。只把 next 放进未等待的 Promise,错误会丢。
追问
和前端拦截器像吗?
像一条管道。差别是中间件跑在服务器上,能信任。浏览器里的拦截器用户可以绕过,鉴权不能只放在那里。
怎么测试?
给中间件假的 req、res 和 next,断言它是否调用 next、是否写了状态码。不要为了测鉴权去把整个框架拉起来,除非你在测路由顺序。
易错点
- 调用了
next之后又res.send,出现「已发送」的错误。 - 异步函数抛错没人接,请求一直转圈。
- 鉴权中间件写在路由之后,请求根本不会经过它。