使用Express NodeJS调用控制器无法获取数据并报ERR_HTTP_HEADERS_SENT错误
问题根因
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client 报错的核心原因是同一个HTTP请求被多次返回响应:
你当前的userData、getActivities两个工具函数内部直接调用了res.json()/res.status()给客户端返回响应,你在DataMatching控制器中调用这两个函数时,它们已经把响应发送给客户端了,后续DataMatching自己执行res.json()的时候就会触发重复发送响应的报错。
修复方案
核心调整逻辑是:工具层只负责返回业务数据/抛出错误,所有响应返回逻辑统一由入口控制器DataMatching处理,避免多位置返回响应。
1. 修改userData函数
删除内部返回响应的逻辑,直接返回请求到的用户数据,出错时抛出错误即可:
const axios = require('axios'); const userData = async (req) => { try { let res_user = await axios.get(somePath, someConfig) if (res_user.data.success === true) { // 直接返回业务数据,不调用res相关方法 return res_user.data } else { // 出错直接抛出,上层统一捕获处理 throw new Error(res_user.data.message) } } catch (error) { throw error } } module.exports = { userData }
2. 修改getActivities函数
同理删除内部响应逻辑,直接返回数据库查询结果:
const Activity = require('../models/activity'); const getActivities = async (req) => { try { const activities = await Activity.find().populate('tags') // 直接返回查询到的活动数据 return activities } catch (error) { throw error } } module.exports = { getActivities }
3. 修改DataMatching控制器
统一处理所有数据和异常,最终返回响应:
const { response } = require('express'); const { userData } = require("./userData"); const { getActivities } = require("./activities"); const DataMatching = async (req, res = response) => { let userTags = []; let activities = []; let state = false; let topActivities= {}; try { // 现在拿到的是直接的业务数据,不是响应对象 const userDataResult = await userData(req); activities = await getActivities(req); if (userDataResult.tags && activities){ userTags = userDataResult.tags; state = true; // 原有业务逻辑 } return res.json({ ok: state, response: topActivities }); } catch (error) { return res.status(500).json({ ok: state, response: error.message }); } } module.exports = { DataMatching }
关于try代码块的疑问
不需要把所有逻辑都塞进try块,只需要把可能抛出异常的异步操作、不确定是否会出错的逻辑放到try块中即可。同步的、确定不会出错的逻辑(比如简单的变量赋值、数组遍历等)可以放在try块外面,也可以放在里面,根据代码可读性调整即可。
你当前的场景中两个异步数据获取操作都可能出错,放到同一个try块中统一捕获处理,可以简化错误处理逻辑,避免每个异步操作单独写catch的冗余代码,是合理的写法。
内容的提问来源于stack exchange,提问作者Josué Venegas
相关产品推荐
相关产品推荐

