You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 08:15:04