Express登录接口报ERR_HTTP_HEADERS_SENT及UnhandledPromiseRejectionWarning错误
错误排查与修复方案
错误原因
- 触发
ERR_HTTP_HEADERS_SENT的核心问题:Express 同一次请求中只能发送一次响应,你的代码在!user、密码不匹配两个分支调用res.status().json()发送响应后,没有添加return终止函数执行,代码会继续向下运行,触发后续的响应发送逻辑,导致同一次请求多次发送响应,抛出该错误。 - 触发未处理Promise拒绝的原因:当用户不存在时,
user为null,由于你没有在!user分支终止代码,后续执行CryptoJS.AES.decrypt(user.password, ...)时访问null.password会抛出异常,此时前面已经发送过响应,catch代码块中再次调用res.status(500).json()会二次触发响应发送逻辑,进而抛出未处理Promise拒绝警告。
修复方案
在所有发送响应的分支后添加return,确保发送响应后终止后续代码执行,修正后代码如下:
router.post("/login", async (req, res) => { try { const user = await User.findOne({ email: req.body.email }); if (!user) { return res.status(401).json("Something went wrong!"); } const bytes = CryptoJS.AES.decrypt(user.password, process.env.SECRET_KEY); const originalPassword = bytes.toString(CryptoJS.enc.Utf8); if (originalPassword !== req.body.password) { return res.status(401).json("Something went wrong!"); } return res.status(200).json(user); } catch (err) { return res.status(500).json(err); } }); module.exports = router;
优化建议
- 生产环境建议不要直接返回原始错误对象
err到前端,避免泄露服务端路径、依赖等敏感信息,可替换为通用错误提示如"服务器内部错误" - 登录失败的提示可以更精准区分用户不存在、密码错误两种情况,也可以统一提示
"邮箱或密码错误"避免被恶意枚举用户
内容的提问来源于stack exchange,提问作者BlaBlue
相关产品推荐
相关产品推荐

