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

如何修复NodeAPI搭配Angular时的ERR_HTTP_HEADERS_SENT错误

问题分析与解决方案

核心问题

  1. CORS预检请求未正确处理:浏览器发起的OPTIONS预检请求不会携带Authorization头,你的checkRole函数会因找不到token返回401,导致浏览器拦截后续实际GET请求。同时预检请求要求服务器返回200/204并附带正确CORS头,否则会触发跨域错误。
  2. checkRole函数逻辑漏洞:
    • 混用async/await和then/catch,导致代码执行流程混乱
    • 当foundUser不存在时,既未返回响应也未调用next(),会造成请求挂起,进而触发重复发送响应的错误
    • 条件判断foundUser.role != null || foundUser.role != ''逻辑错误,应使用&&(一个值不可能同时为null和空字符串,原判断会导致所有情况都进入分支)

修复步骤

1. 正确处理CORS预检请求

在Express应用中添加全局中间件,优先处理OPTIONS请求并返回正确CORS头:

// 放在所有路由之前的全局中间件
app.use((req, res, next) => {
  // 根据实际需求调整允许的源、方法和请求头
  res.setHeader('Access-Control-Allow-Origin', '你的Angular应用域名');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  
  // 预检OPTIONS请求直接返回204
  if (req.method === 'OPTIONS') {
    return res.sendStatus(204);
  }
  next();
});

也可以使用cors包简化配置(推荐):

npm install cors

在应用中引入并配置:

const cors = require('cors');

app.use(cors({
  origin: '你的Angular应用域名',
  allowedHeaders: ['Content-Type', 'Authorization'],
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']
}));

2. 重构checkRole函数逻辑

统一使用async/await,修复条件判断和分支覆盖问题:

const checkRole = async (req, res, next) => {
  // 若使用cors包,可省略此判断(cors会自动处理OPTIONS请求)
  if (req.method === 'OPTIONS') {
    return next();
  }

  try {
    // 先校验Authorization头是否存在
    if (!req.headers.authorization) {
      return res.sendStatus(401);
    }

    const token = req.headers.authorization.split(' ')[1];
    const decodedToken = jwt.verify(token, envs.jwtSecret);

    const foundUser = await User.findById(decodedToken.userId);
    if (!foundUser) {
      return res.sendStatus(401);
    }

    // 修复条件判断:确保role既非null也非空字符串
    if (foundUser.role != null && foundUser.role !== '') {
      if (foundUser.role.includes('Admin')) {
        req.userData = {
          email: decodedToken.email,
          id: decodedToken.id
        };
        return next();
      }
    }
    // 所有不满足Admin权限的情况统一返回401
    return res.sendStatus(401);

  } catch (error) {
    // 捕获token解析、数据库查询等错误,统一返回401
    return res.sendStatus(401);
  }
};

3. 验证修复效果

  • 启动Node API和Angular应用,查看网络面板:OPTIONS请求将返回204,实际GET请求会正常携带token并通过权限校验
  • 控制台不再出现ERR_HTTP_HEADERS_SENT错误(原错误因分支逻辑不完整导致多次发送响应,修复后分支覆盖完整)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 05:00:54