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

MEAN栈API关注功能报错Error [ERR_HTTP_HEADERS_SENT]求助

解决MEAN栈关注功能中的ERR_HTTP_HEADERS_SENT错误

你的代码出现Cannot set headers after they are sent to the client错误的核心原因是混用了async/await和回调函数,同时存在参数语法错误和拼写错误,导致多次向客户端发送响应。以下是具体问题和修复方案:

具体问题分析

  1. 混用async/await与回调函数:findByIdAndUpdate同时使用await和回调函数,回调里的res.status(201).json(docs)会先发送响应,后续操作或错误处理又尝试发送响应,触发重复响应错误。
  2. 参数结构错误:第一个findByIdAndUpdate的第三个参数应该是配置选项(如new: true),但你传入了另一个更新对象{ $push: { following: req.body.followerId } },语法完全错误。
  3. 拼写错误:两处res.status(400).jsos(err)中的jsos是json的笔误。
  4. 逻辑冗余:关注逻辑应该是当前用户(req.params.id)的following数组添加目标用户ID(req.body.idToFollow),目标用户的followers数组添加当前用户ID,你额外添加的req.body.followerId属于冗余逻辑。

修复后的完整代码

const ObjectId = require('mongoose').Types.ObjectId; // 确保已引入ObjectId

module.exports.follow = async (req, res) => {
  // 验证当前用户ID是否合法
  if (!ObjectId.isValid(req.params.id)) {
    return res.status(400).send(`ID unknown: ${req.params.id}`);
  }

  const { idToFollow } = req.body;
  // 验证目标用户ID是否合法
  if (!idToFollow || !ObjectId.isValid(idToFollow)) {
    return res.status(400).send('Invalid target user ID');
  }

  // 避免用户关注自己
  if (req.params.id === idToFollow) {
    return res.status(400).send('Cannot follow yourself');
  }

  try {
    // 更新当前用户的following列表
    const currentUser = await User.findByIdAndUpdate(
      req.params.id,
      { $addToSet: { following: idToFollow } }, // 使用$addToSet避免重复关注
      { new: true, runValidators: true } // new: true返回更新后的文档,runValidators启用验证
    );

    if (!currentUser) {
      return res.status(404).send('Current user not found');
    }

    // 更新目标用户的followers列表
    const targetUser = await User.findByIdAndUpdate(
      idToFollow,
      { $addToSet: { followers: req.params.id } },
      { new: true, runValidators: true }
    );

    if (!targetUser) {
      return res.status(404).send('Target user not found');
    }

    // 所有操作完成后发送一次成功响应
    return res.status(201).json({
      currentUser: { id: currentUser._id, following: currentUser.following },
      targetUser: { id: targetUser._id, followers: targetUser.followers }
    });
  } catch (err) {
    return res.status(500).json({ message: err.message });
  }
};

关键修改说明

  • 移除回调函数:完全使用async/await处理异步操作,避免回调导致的重复响应。
  • 修正参数结构:将更新逻辑合并到第二个参数,第三个参数仅传入配置选项。
  • 添加参数验证:增加对idToFollow的合法性检查,以及用户不能关注自己的逻辑。
  • 统一响应时机:仅在所有数据库操作成功完成后发送一次响应,错误通过try/catch统一捕获处理。
  • 修复拼写错误:将jsos改为正确的json。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 00:50:20