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

Angular 18本地请求后应用崩溃问题排查

Angular 18 企业代理环境下POST/PUT/DELETE请求触发ERR_HTTP_HEADERS_SENT错误分析

问题场景

已将Angular应用升级至18版本,处于企业代理环境中,代理配置文件如下:

let proxyConfig = {
  '/test/**': {
    target: 'https://myUrl/test',
    secure: true,
    changeOrigin: true,
    logLevel: 'debug',
    pathRewrite: { '^/test': '' },
  }
}

function setupForCorporateProxy(proxyConfig) {
  const proxyServer = process.env.http_proxy || process.env.HTTP_PROXY;
  if (proxyServer) {
    const agent = new HttpsProxyAgent(proxyServer);
    Object.keys(proxyConfig).forEach(function (key) {
      proxyConfig[key].agent = agent;
    });
  }
  return proxyConfig;
}

module.exports = setupForCorporateProxy(proxyConfig);

升级后本地请求全部失败,将代理配置路径中的单个*改为**后GET请求恢复,但POST/PUT/DELETE请求仍触发以下错误导致应用崩溃:

node:_http_outgoing:659
throw new ERR_HTTP_HEADERS_SENT('set');
^

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ClientRequest.setHeader (node:_http_outgoing:659:11)
    at setOriginHeader (file:///myPath/node_modules/vite/dist/node/chunks/dep-C1-ZB6nQ.js:61834:16)
    at ProxyServer.<anonymous> (file:///myPath/node_modules/vite/dist/node/chunks/dep-C1-ZB6nQ.js:61887:7)
    at ProxyServer.emit (file:///myPath/node_modules/vite/dist/node/chunks/dep-C1-ZB6nQ.js:59914:36)
    at ClientRequest.<anonymous> (file:///myPath/node_modules/vite/dist/node/chunks/dep-C1-ZB6nQ.js:61332:16)
    at ClientRequest.emit (node:events:531:35)
    at tickOnSocket (node:_http_client:839:7)
    at onSocketNT (node:_http_client:902:5)
    at process.processTicksAndRejections (node:internal/process/task_queues:83:21) {
  code: 'ERR_HTTP_HEADERS_SENT'
}
Node.js v20.15.0

问题原因

  1. Angular 18 底层Dev Server切换为Vite:Angular 18默认使用Vite替代原有的Webpack Dev Server,两者代理实现逻辑存在差异。Vite的代理基于新版http-proxy-middleware,对请求头的处理时机和顺序要求更严格。
  2. 企业代理Agent与Vite代理头处理冲突:给代理目标添加HttpsProxyAgent后,Vite的代理逻辑会尝试在请求发送后再次修改Origin头(报错栈中的setOriginHeader函数可佐证),此时请求已通过企业代理Agent发出,响应头开始返回,重复设置头直接触发错误。
  3. 请求方法差异导致触发条件不同:GET请求通常无请求体,头处理时机更早,未暴露冲突;而POST/PUT/DELETE带有请求体,请求生命周期更长,Vite在处理完请求体后再尝试修改Origin头,此时企业代理已开始发送请求,头已被发送,从而触发报错。
  4. 路径匹配的隐性影响:将*改为**仅解决了GET请求的路径匹配问题,并未触及代理头处理的核心冲突,只是让GET请求的头处理流程避开了冲突点。

验证与修复方向

  • 禁用Vite代理的changeOrigin配置,手动设置Origin头,避免Vite自动修改头的逻辑:
    '/test/**': {
      target: 'https://myUrl/test',
      secure: true,
      changeOrigin: false,
      headers: {
        Origin: 'https://myUrl/test'
      },
      logLevel: 'debug',
      pathRewrite: { '^/test': '' },
    }
    
  • 检查HttpsProxyAgent版本,确保与Vite依赖的http-proxy-middleware版本兼容,避免Agent内部提前发送请求头。
  • 将企业代理的Agent配置改为Vite全局代理设置,而非添加到单个代理规则中,示例vite.config.ts配置:
    import { defineConfig } from 'vite';
    import angular from '@angular-devkit/build-angular/src/vite/index.js';
    import HttpsProxyAgent from 'https-proxy-agent';
    
    export default defineConfig({
      plugins: [angular()],
      server: {
        proxy: {
          '/test/**': {
            target: 'https://myUrl/test',
            secure: true,
            changeOrigin: true,
            logLevel: 'debug',
            pathRewrite: { '^/test': '' },
          }
        },
        httpAgent: process.env.http_proxy ? new HttpsProxyAgent(process.env.http_proxy) : undefined,
        httpsAgent: process.env.http_proxy ? new HttpsProxyAgent(process.env.http_proxy) : undefined
      }
    });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 18:15:16