中间件
我们在这篇文章主要分析的是路由层。
中间件其实就是一个处理函数,一个请求到来之后会交给express处理。express里有一个映射:请求方法和请求路径执行相应的中间件。
app.get("/news",
(req, res)=>{
// handler1
},
(req, res)=>{
// handler2
})
app.get("/news",(req, res)=>{
// handler3
})
我们可以写多个处理函数,一个处理函数就是一个中间件。 中间件匹配到了请求后,会根据映射表交给第一个处理函数进行处理。
我们给服务器发起请求时,只运行了第一个处理函数。后续的处理函数需要手动的交给下一个中间件。需要用到第三个参数 next。
app.get("/news",(req, res, next)=>{
// handler1
next();
})
依次往后移交就可以实现完整的处理过程。
如果一直往后移交,由于后续已经没有中间件,此时请求还没有结束会自动的响应给客户端 404。
app.get("/news",(req, res, next)=>{
// handler1
next();
res.end();
})
如果之前的中间件已经处理完响应,后续的中间件就不会处理。后续的函数还是可以执行的。
中间件还有一种情况就是报错
app.get("/news",(req, res, next)=>{
throw newError()
// 相当于
next(new Error())
})
报错后不会停止服务器,而是运行 next(new Error())
。寻找后续的错误处理中间件,如果没有则响应 500 状态码。
获取错误
app.get("/news",(err, req, res, next)=>{
// 通过 err 参数即可处理错误
// 如果 err 有值
if(err){
res.status(500).send({
code: 500,
msg: err
})
}else{
next();
}
})
一般我们通常使用 use 的方式书写中间件
app.use("/news", (err, req, res, next)=>{
})
使用use时不写第一个参数就会匹配任何请求。
区别在于匹配的是基地址,只要以路径段开头都能匹配。use的匹配范围更广。在中间件中可以获得 baseUrl
。
在业务开发中我们通常会这样写
(req, res, next)=>{
if(req.path.startWith("/api")){
//说明请求的是 api 接口
next();
}else{
// 说明请求的是静态资源
}
}