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

Postman请求Node异步路由返回Cannot GET及响应头重复设置报错问题

问题根因

你的错误完全来自validateToken中间件的错误写法,和MongoDB/Mongoose无关:

  • 中间件末尾有一个全局的next()调用,没有放在任何逻辑分支内。jwt.verify是异步执行的,代码运行时会先触发这个全局next(),提前进入路由处理逻辑,此时req.decodedJwt还未赋值,路由中访问req.decodedJwt.username会直接抛出未定义错误,触发框架默认错误响应,HTTP头已经被发送。
  • 等jwt.verify异步回调执行完成后,要么会返回401响应,要么会再次调用next()执行路由逻辑,此时再次尝试发送响应就会触发Cannot set headers after they are sent to the client报错。
  • 路由代码中console.log(query)的query变量未定义,也会额外抛出未捕获异常。

修复方案

1. 修复validateToken中间件

删除末尾多余的next(),所有返回响应的分支添加return避免后续代码执行:

module.exports = (req, res, next) => {
  const token = req.headers.authorization;
  if (token) {
    jwt.verify(token, jwtSecret, (err, decoded) => {
      if (err) {
        console.log("\n!!!~~~Sending response~~~!!!\n")
        return res.status(401).json('Please supply a valid token')
      } 
      req.decodedJwt = decoded;
      next();
    })
  } else {
    console.log("\n!!!~~~Sending response~~~!!!\n")
    return res.status(401).json("You must have a token to do that");
  }
}

2. 修复路由代码

删除未定义的query变量打印,因为你的Schema中username是唯一值,建议用findOne替代find减少不必要的返回:

router.get('/fetch', validateToken, async (req, res) => {
  try {
    const user = req.decodedJwt.username;
    const data = await Todo.findOne({username: user});
    res.json(data)
  } catch (err) {
    console.log(err)
    res.status(500).json(err)
  }
})

内容的提问来源于stack exchange,提问作者Archa9

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 20:24:06