Express中间件报错Cannot set headers after they are sent求助
问题根因
你遇到的[ERR_HTTP_HEADERS_SENT]错误核心原因是同一个请求流程中多次向客户端发送响应/触发后续响应逻辑,具体问题出在三处:
- 你在
if (req.cookies)的代码块外直接调用了next(),而verify()是异步函数,它的.then()/.catch逻辑还没执行完成时,外层的next()就已经先触发后续中间件/路由返回响应了。等异步逻辑执行完成后,你又在.then()里调用next()、或是在.catch()里调用res.redirect('/'),就会重复操作响应头,触发报错。 - 存在变量命名冲突问题:外层已经声明了
let user = {},在.then()回调里又声明了同名的const user = await User.find(...),容易引发逻辑异常。 - 边界逻辑缺失:如果
req.cookies不存在、或者session-token为空的场景,直接调用next()会导致后续逻辑读取req.user时报错。
修复后的代码
app.use(async function addReqUser(req,res,next) { // 没有cookies或者没有session-token直接走后续逻辑,可按需调整为拦截逻辑 if (!req.cookies || !req.cookies['session-token']) { return next() } let token = req.cookies['session-token']; let userInfo = {}; // 改名避免和后续数据库查询结果重名 async function verify() { //google auth function const ticket = await client.verifyIdToken({ idToken: token, audience: CLIENT_ID, }); const payload = ticket.getPayload(); userInfo.name = payload.name; userInfo.email = payload.email; userInfo.picture = payload.picture; } verify() .then(async ()=>{ req.user = userInfo; // 修改变量名避免命名冲突 const dbUser = await User.find({ email: req.user.email }).select("_id").exec(); req.user.id = dbUser[0]._id res.locals.user = req.user // 异步逻辑执行完成后再调用next next(); }) .catch(err=>{ console.log(err) return res.redirect('/') }) })
内容的提问来源于stack exchange,提问作者Saswat
相关产品推荐
相关产品推荐

