Node.js更新个人资料API出现Error [ERR_HTTP_HEADERS_SENT]问题求助
问题分析与修复方案
核心错误原因:重复发送HTTP响应
你遇到的Error [ERR_HTTP_HEADERS_SENT]是因为代码中多次调用了res.send()相关方法,导致向客户端发送了多份响应头。
具体问题出在这段代码:
const user = new User(req.body, rules); user.save(err => { if (err) { res.status(500).send({ message: err }); return; } });
这里的user.save()是异步回调形式,当保存出错时会发送500响应,但回调函数的return只会终止当前回调,不会阻止后续代码执行。后续代码仍会继续执行到最后的return res.status(200).send(...),导致重复发送响应。
而且这段代码本身是多余的——你后面已经用User.updateOne()更新了用户数据,前面创建新用户并保存的操作完全没必要,属于冗余代码。
其他代码问题及修复
除了核心错误,代码里还有几个需要修正的问题:
- 变量未定义就使用
var image_file_name = Date.now() + '-Profile-images-' + image_file_name;
这里右边的image_file_name还未定义就拼接,会导致NaN-Profile-images-undefined这种错误文件名,应该改为使用上传文件的原始名称:
var image_file_name = Date.now() + '-Profile-images-' + image_file.name;
- 图片路径判断逻辑错误
if (current_user.profile_image && current_user.profile_image == '') {
这里的逻辑矛盾——current_user.profile_image有值时才会进入判断,但又判断它等于空字符串,应该改为:
if (current_user.profile_image && current_user.profile_image !== '') {
同时注意大小写一致性:代码里混用了profile_image和Profile_images,要统一为数据库字段名(比如profile_image)。
- 同步文件操作的风险
fs.unlinkSync()是同步操作,会阻塞事件循环,建议改为异步版本fs.unlink():
if (fs.existsSync(old_path)) { fs.unlink(old_path, (err) => { if (err) console.error('删除旧图片失败:', err); }); }
完整修复后的代码
exports.update_profile = async (req, res) => { try { let current_user = req.User; let image_file_name = current_user.profile_image; if (req.files && req.files.Profile_images) { const image_file = req.files.Profile_images; image_file_name = Date.now() + '-Profile-images-' + image_file.name; const image_path = publicPath + '/Profile_images/' + image_file_name; await image_file.mv(image_path); // 删除旧图片 if (current_user.profile_image && current_user.profile_image !== '') { const old_path = publicPath + '/Profile_images/' + current_user.profile_image; if (fs.existsSync(old_path)) { fs.unlink(old_path, (err) => { if (err) console.error('删除旧图片失败:', err); }); } } } // 更新用户数据 await User.updateOne( { _id: current_user._id }, { username: req.body.username, email: req.body.email, mobile: req.body.mobile, companyname: req.body.companyname, profile_image: image_file_name, profession: req.body.profession || '' } ); const userData = await User.findOne({ _id: current_user._id }); const jwt_secret = process.env.JWT_SECRET || 'mysecret'; const token = jwt.sign({ data: userData }, jwt_secret, { expiresIn: '12h' }); return res.status(200).send({ message: 'Profile Updated Successfully', data: userData, token: token }); } catch (error) { return res.status(404).send({ message: error.message }); } }
关键优化点总结
- 移除了冗余的
new User()和user.save()操作,避免重复响应和无效数据库操作 - 修复了变量未定义的问题,确保文件名生成正确
- 修正了图片删除的逻辑判断,统一字段名大小写
- 将同步文件删除改为异步,避免阻塞事件循环
- 确保整个函数中只有一次响应发送,彻底解决
ERR_HTTP_HEADERS_SENT错误
内容的提问来源于stack exchange,提问作者Max_07
相关产品推荐
相关产品推荐

