@Error[ERR_HTTP_HEADERS_SENT]:Cannot set headers after they are sent to the client
背景
express 中间件中 next() 并不会阻断后面代码执行,如果后面继续对res的操作或者返回 就会导致 第二次响应,即下边的错误。
代码如下:
app.use((req,res,next)=>{
// 包含登录的放行
if(req.url.includes("login")){
next()
}
// 有session的 校验session是否通过(登录之后 设置loginStatus:1)
if(req.session.loginStatus === 1){
next()
}else{
if(req.url.includes("api")){// 接口 返回错误码
res.status(401).json({ok:0})
}else{// 非接口 重定向到login
res.redirect("/login",{title:"login page"})
}
}
})
运行结果及报错内容
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:561:11)
at ServerResponse.header (E:\node\preject\050-登录鉴权\myapp\node_modules\express\lib\response.js:767:10)
at ServerResponse.contentType (E:\node\preject\050-登录鉴权\myapp\node_modules\express\lib\response.js:595:15)
at ServerResponse.send (E:\node\preject\050-登录鉴权\myapp\node_modules\express\lib\response.js:145:14)
at done (E:\node\preject\050-登录鉴权\myapp\node_modules\express\lib\response.js:1004:10)
at tryHandleCache (E:\node\preject\050-登录鉴权\myapp\node_modules\ejs\lib\ejs.js:260:5)
at View.exports.renderFile [as engine] (E:\node\preject\050-登录鉴权\myapp\node_modules\ejs\lib\ejs.js:485:10)
at View.render (E:\node\preject\050-登录鉴权\myapp\node_modules\express\lib\view.js:135:8)
at tryRender (E:\node\preject\050-登录鉴权\myapp\node_modules\express\lib\application.js:640:10)
at Function.render (E:\node\preject\050-登录鉴权\myapp\node_modules\express\lib\application.js:592:3)
定位问题
- 先排查是哪段代码出现了问题
- 分析为甚么会出现这种问题
- 借助debugger工具查看程序有没有按照预期的顺序执行
- 发现includes(login)的请求在next之后,又走了redirect从而导致报错
解决思路:
阻止next()后面的代码执行,以下两种方法
- return
- 做if else分支确保next()后不再执行
app.use((req,res,next)=>{
// 包含登录的放行
if(req.url.includes("login")){
next()
}else{
// 有session的 校验session是否通过(登录之后 设置loginStatus:1)
if(req.session.loginStatus === 1){
next()
}else{
if(req.url.includes("api")){// 接口 返回错误码
res.status(401).json({ok:0})
}else{// 非接口 重定向到login
res.redirect("/login")
}
}
}
})