MEAN栈API关注功能报错Error [ERR_HTTP_HEADERS_SENT]求助
解决MEAN栈关注功能中的
ERR_HTTP_HEADERS_SENT错误 你的代码出现Cannot set headers after they are sent to the client错误的核心原因是混用了async/await和回调函数,同时存在参数语法错误和拼写错误,导致多次向客户端发送响应。以下是具体问题和修复方案:
具体问题分析
- 混用async/await与回调函数:
findByIdAndUpdate同时使用await和回调函数,回调里的res.status(201).json(docs)会先发送响应,后续操作或错误处理又尝试发送响应,触发重复响应错误。 - 参数结构错误:第一个
findByIdAndUpdate的第三个参数应该是配置选项(如new: true),但你传入了另一个更新对象{ $push: { following: req.body.followerId } },语法完全错误。 - 拼写错误:两处
res.status(400).jsos(err)中的jsos是json的笔误。 - 逻辑冗余:关注逻辑应该是当前用户(
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
相关产品推荐
相关产品推荐

