Node.js报错Cannot set headers after they are sent to the client求助
解决Node.js "Cannot set headers after they are sent to the client" 错误
你的问题出在extractUser中间件的逻辑漏洞上:当请求不存在userToken Cookie时,next()会被调用两次,导致后续控制器函数执行两次。第一次控制器发送响应后,第二次再尝试发送响应时,就会触发"Cannot set headers after they are sent to the client"错误。
问题代码分析
当!token为真时,你设置res.locals.user = null并调用next(),但没有终止函数执行,代码会继续进入后面的try块:
- 此时
token为undefined,jwt.verify(token, ...)会抛出错误,进入catch块,再次调用next() - 两次调用
next()会让控制器函数执行两次,第一次发送响应后,第二次再执行res.status(200).json(...)或res.sendStatus(400)时,响应头已被发送,触发错误
修复后的中间件代码
只需在if(!token)分支的next()后添加return,终止函数后续逻辑执行;同时补充User.findById的错误捕获,避免未处理的Promise异常:
function extractUser(req, res, next) { let token = req.cookies.userToken; if (!token) { res.locals.user = null; return next(); // 添加return,阻止代码进入后续try块 } try { let { id } = jwt.verify(token, SERVER_SECRET); if (id) { User.findById(id) .then(user => { res.locals.user = user; next(); }) .catch(err => { // 捕获数据库查询异常 res.locals.user = null; next(); }); } else { res.locals.user = null; next(); } } catch (err) { res.locals.user = null; next(); } }
也可以用else包裹后续逻辑,确保只有当token存在时才执行验证流程:
function extractUser(req, res, next) { let token = req.cookies.userToken; if (!token) { res.locals.user = null; next(); } else { try { let { id } = jwt.verify(token, SERVER_SECRET); if (id) { User.findById(id) .then(user => { res.locals.user = user; next(); }) .catch(err => { res.locals.user = null; next(); }); } else { res.locals.user = null; next(); } } catch (err) { res.locals.user = null; next(); } } }
内容的提问来源于stack exchange,提问作者M.KH
相关产品推荐
相关产品推荐

