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

Node.js中ERR_HTTP_HEADERS_SENT错误及MongoDB集合数据返回问题

问题解决:Error [ERR_HTTP_HEADERS_SENT] 及MongoDB集合数据返回问题

报错信息

Error [ERR_HTTP_HEADERS_SENT] Cannot set headers after they are sent to the client

代码片段

router.get("/showCollections",(req,res,next)=>{
  console.log("in showCollections");
  
  
  const collectionsNames=[];
  const dataToSend = []

  mongoose.connection.db.listCollections().toArray(function(err, names){
    for(let i=0;i<names.length;i++){
      collectionName=names[i].name;
      if(collectionName.localeCompare("users")!=0){
        // console.log(names[i].name);
        collectionsNames.push(collectionName);
      }
    }
    for (let i = 0;i < collectionsNames.length;i++) {
      mongoose.connection.db.collection(collectionsNames[i], function (err, collection) {
        collection.find({}).toArray(function(err,data){
          dataToSend.push(data[i]);//想要在循环外部访问这个数组,作为响应发送给前端
          // console.log(data);
        })
      })
      
    }
  })
})

需求与问题

想要把MongoDB里所有集合的数据发送给前端,目标是把dataToSend数组作为响应返回,但现在数组在循环外面拿不到正确的内容,还触发了上面的HTTP头部错误。

解决方法

为啥会出这些问题

  1. 异步操作没处理好:你用的是回调式的MongoDB操作,循环里的collection.find({}).toArray()都是异步执行的——等你想在循环外读取dataToSend时,这些查询根本还没跑完,数组自然是空的。
  2. HTTP头部错误的原因:要是你之前试过在回调里多次调用res.send(),就会触发这个错误——因为响应只能发送一次,重复调用就会重复设置HTTP头部,服务器直接报错。

修复后的代码(用async/await搞定异步)

router.get("/showCollections", async (req, res, next) => {
  console.log("in showCollections");
  try {
    // 先获取所有集合名称,排除users集合
    const names = await mongoose.connection.db.listCollections().toArray();
    const collectionsNames = names
      .map(item => item.name)
      .filter(name => name !== "users");

    // 并行查询所有集合的数据,等全部完成再处理
    const dataToSend = await Promise.all(
      collectionsNames.map(async (colName) => {
        const collection = await mongoose.connection.db.collection(colName);
        return collection.find({}).toArray();
      })
    );

    // 把数据返回给前端
    res.status(200).json(dataToSend);
  } catch (err) {
    // 捕获错误并返回给前端
    console.error(err);
    res.status(500).json({ error: "获取集合数据失败" });
  }
});

修复说明

  • 改用async/await语法,替代嵌套回调,代码逻辑更清晰,避免回调地狱。
  • 使用Promise.all()并行处理所有集合的查询,既提升效率,又能确保所有数据都查询完成后再统一返回。
  • 用try/catch包裹整个逻辑,及时捕获并处理异常,避免服务崩溃。
  • 只调用一次res.json()发送响应,从根源上解决ERR_HTTP_HEADERS_SENT错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 17:45:37