Node.js登录接口ERR_HTTP_HEADERS_SENT错误排查求助
问题解决:ERR_HTTP_HEADERS_SENT 错误原因及修复
你的登录函数触发ERR_HTTP_HEADERS_SENT错误的核心原因是:在返回错误响应后没有终止函数执行,导致后续代码继续尝试发送新的响应,同一个请求中多次设置响应头引发冲突。
具体错误点分析
- 当用户不存在(
!user)时,你返回了404响应,但函数并未停止,后续代码会继续执行const decryptedPassword = await CryptoJS.AES.decrypt(user.password...)——此时user是undefined,访问user.password会抛出错误,进入catch块再次返回500响应,造成两次发送响应头。 - 当密码不匹配时,你返回了
401响应,但同样没有终止函数,后续代码会继续执行res.status(200).json(user),再次发送响应,触发错误。
修复后的登录函数代码
import CryptoJS from "crypto-js"; import User from "../models/user.js"; import Jwt from "jsonwebtoken"; // login function export const login = async (req, res) => { try { const user = await User.findOne({ email: req.body.email }); if (!user) { // 返回响应后立即终止函数 return res.status(404).json(" User not found "); } // CryptoJS.decrypt是同步操作,不需要await const decryptedPassword = CryptoJS.AES.decrypt(user.password, process.env.SECRET_KEY).toString(CryptoJS.enc.Utf8); if (decryptedPassword !== req.body.password) { // 返回响应后立即终止函数 return res.status(401).json("Wrong password "); } res.status(200).json(user); } catch (error) { res.status(500).json(error); } }
额外优化提示
CryptoJS.AES.decrypt是同步方法,不需要使用await,可以去掉多余的await关键字,避免不必要的异步等待。- 也可以用
else语句控制代码分支,确保每个响应只会发送一次:
if (!user) { res.status(404).json(" User not found "); } else { const decryptedPassword = CryptoJS.AES.decrypt(user.password, process.env.SECRET_KEY).toString(CryptoJS.enc.Utf8); if (decryptedPassword !== req.body.password) { res.status(401).json("Wrong password "); } else { res.status(200).json(user); } }
内容的提问来源于stack exchange,提问作者madhawa
相关产品推荐
相关产品推荐

