Express密码校验出现Cannot set headers after they are sent to client错误
错误根因
你遇到的Error [ERR_HTTP_HEADERS_SENT]报错是因为同一个请求流程中多次向客户端发送了响应,Express不允许在响应已经返回给客户端后再修改响应头或发送响应内容。
你的代码触发问题的具体逻辑:
- 当查询到用户不存在时,你调用了
res.status(404).json("user not found")返回了404响应,但没有终止后续代码执行 - 代码会继续往下走到
const validPassword = await bcrypt.compare(req.body.password, user.password)这一行,此时user是undefined,访问user.password会抛出异常 - 异常被catch捕获后,你又调用了
res.status(500).json(err)返回500响应,相当于同一个请求发了两次响应,触发报错
同理如果密码校验不通过时,你返回400响应后没有终止代码,后续如果有其他返回响应的逻辑也会触发同样的问题。
修复方案
只需要在每次调用res.json()发送响应后加上return,终止当前请求的后续代码执行即可,更推荐把短路判断改成if写法提升可读性,修复后的代码如下:
try { const user = await User.findOne({ email: req.body.email }); if (!user) { return res.status(404).json("user not found"); } const validPassword = await bcrypt.compare( req.body.password, user.password ); if (!validPassword) { return res.status(400).json("wrong password"); } // 此处写校验通过后的正常业务逻辑,比如生成token、返回用户信息等 } catch (err) { return res.status(500).json(err); }
内容的提问来源于stack exchange,提问作者Usyntest
相关产品推荐
相关产品推荐

