Express使用express-session报ERR_HTTP_HEADERS_SENT错误如何解决
问题根因
报Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client的原因非常明确:一次请求里你给客户端返回了不止一次响应。Express只要把响应头发给客户端了,就不许再改响应头、再发新内容,你代码里好几处发完响应没停,继续往下跑逻辑发第二次响应,就会报这个错。
具体踩的坑:
- 数据库查询出错时,你调用
res.send()发了错误提示,但没终止代码,后面还是会继续判断查询结果、甚至跑最后面的res.end(),等于连续发响应 - 登录成功走
res.redirect("/home")跳转本身就已经发响应了,但是你在查询回调最后写了个统一的res.end(),跳转完代码还是会跑到这行,再发一次响应 - 你把
req.session.regenerate和req.session.save里的错误处理全注释了,这俩步骤要是出问题,代码不会停,还是会往下跑 - 多余的
res.end():res.send、res.redirect这俩方法自己就会结束响应,根本不需要你手动再调一次res.end()
修复方法
- 所有分支只要调用了
res.send、res.redirect发响应,前面加return,直接终止函数执行,别让代码往下跑 - 删掉数据库查询回调最外层那个多余的
res.end() - 把之前注释掉的session操作错误处理补上,真出问题直接返回错误,别继续跑逻辑
- 额外提一句:你现在直接明文存密码、查库比对的写法有严重安全隐患,上线前一定要改成密码哈希存储比对,这次先解决你当前遇到的报错问题。
修复后可运行代码
const emailaddress = req.body.emailaddress; const password = req.body.password; if (emailaddress && password) { const query = `SELECT * FROM users where email=? AND password=?`; connection.query( query, [emailaddress, password], function (err, results, fields) { // 数据库出错分支:发完响应直接return终止 if (err) { return res.send({ code: 500, failed: "Error ocurred", }); } if (results.length > 0) { req.session.regenerate(function (err) { // 补全session再生错误处理 if (err) { return res.send({ code: 500, failed: "Session operation failed" }); } req.session.loggedin = true; req.session.emailaddress = req.body.emailaddress; req.session.save(function (err) { // 补全session保存错误处理 if (err) { return res.send({ code: 500, failed: "Session save failed" }); } // 跳转后直接return,不执行后续逻辑 return res.redirect("/home"); }); }); } else { // 账号密码错误分支:发完响应直接return终止 return res.send("Incorrect email address and/or password!"); } } ); } else { res.send("Please enter username and/or password"); res.end(); }
内容的提问来源于stack exchange,提问作者user8510079
相关产品推荐
相关产品推荐

