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

net::ERR_CONNECTION_RESET导致Angular API请求重复?技术求助

解决长流程API的重复执行与浏览器超时问题

看起来你碰到的是典型的长同步请求导致的代理超时+自动重试问题,结合你的场景(.NET中间层+Angular,服务器流程正常但控制器重复执行,前端无重试请求),我来梳理下原因和解决方案:

核心原因分析

你的问题关键点在于:控制器方法重复执行但前端没发对应请求,这说明重试不是浏览器发起的,而是中间的代理服务器(比如IIS、Nginx、云负载均衡)或者.NET自身的配置导致的:

  • 大多数服务器默认的请求超时窗口是5分钟左右,当你的API请求超过这个时间还没返回响应,代理会主动断开连接,并且如果开启了自动重试(很多默认配置会加这个),就会重新发起请求到你的控制器,导致重复执行。
  • IE的连接超时阈值比Chrome更短,所以更早触发net::ERR_CONNECTION_RESET;Chrome默认超时约10分钟,所以10分钟后才提示失败,但其实代理早就开始重试了。
  • 服务器端流程正常是因为第一次请求已经启动了业务逻辑,后续的重试又重复触发了一次,但业务流程本身没有做幂等校验,所以会并行/重复执行。

针对性解决方案

1. 调整服务器/代理的超时与重试配置

首先要把代理层的超时时间拉长到比你的长流程预期时间更长,同时关闭自动重试:

  • 如果用IIS托管.NET应用:
    • 对于.NET Framework:在web.config里修改httpRuntime的executionTimeout(注意要搭配compilation debug="false"才会生效):
      <system.web>
        <httpRuntime executionTimeout="3600" /> <!-- 1小时,根据你的流程调整 -->
      </system.web>
      
    • 对于ASP.NET Core:在Program.cs里配置Kestrel和IIS的超时:
      builder.WebHost.ConfigureKestrel(options =>
      {
          options.Limits.KeepAliveTimeout = TimeSpan.FromHours(1);
      })
      .UseIIS()
      .ConfigureServices(services =>
      {
          services.Configure<IISServerOptions>(options =>
          {
              options.MaxRequestBodySize = int.MaxValue;
              options.AllowSynchronousIO = true; // 如果你的代码是同步的话
          });
      });
      
  • 如果用反向代理(比如Nginx):修改proxy_read_timeout和关闭重试:
    location /api {
        proxy_pass http://your-backend;
        proxy_read_timeout 3600s; # 1小时
        proxy_next_upstream off; # 关闭自动重试
    }
    
  • 云服务场景:比如Azure App Service、AWS EC2负载均衡,要在控制台调整对应的请求超时时间,同时关闭重试策略。

2. 改用异步长流程模式(推荐)

同步挂着等待长流程完成本身就不是最佳实践,更可靠的方式是用“触发-查询”模式:

  • 第一步:触发流程并返回任务ID:
    你的API控制器方法不再等待流程完成,而是立即创建一个后台任务(可以用BackgroundService、Hangfire、Quartz.NET等),然后返回一个唯一的taskId给前端:
    [HttpPost("trigger-long-process")]
    public IActionResult TriggerLongProcess([FromBody] ProcessRequest request)
    {
        var taskId = Guid.NewGuid().ToString();
        // 将任务加入后台队列执行
        _backgroundQueue.QueueBackgroundWorkItem(async token =>
        {
            await _processService.RunLongProcess(request, taskId, token);
        });
        return Ok(new { TaskId = taskId });
    }
    
  • 第二步:前端轮询或实时查询状态:
    Angular前端拿到taskId后,通过定时轮询(比如每30秒一次)或者SignalR实时推送,查询任务的执行状态:
    triggerProcess() {
      this.apiService.triggerLongProcess(request).subscribe(res => {
        this.taskId = res.taskId;
        // 开始轮询状态
        this.statusPolling = interval(30000).subscribe(() => {
          this.apiService.getTaskStatus(this.taskId).subscribe(status => {
            this.processStatus = status;
            if (status === 'Completed' || status === 'Failed') {
              this.statusPolling.unsubscribe();
            }
          });
        });
      });
    }
    
  • 第三步:后台任务处理:后台执行长流程时,把状态更新到数据库或缓存,供查询接口读取。

3. 给长流程接口加幂等校验

如果暂时没法改成异步模式,至少要给控制器方法加幂等校验,防止重复执行:

  • 让前端在请求时带上唯一的requestId,控制器先检查这个requestId是否已经处理过,没处理过再执行流程:
    [HttpPost("long-process")]
    public async Task<IActionResult> LongProcess([FromBody] ProcessRequest request)
    {
        // 检查requestId是否已处理(比如从Redis或数据库查)
        if (_idempotencyService.IsRequestProcessed(request.RequestId))
        {
            return Ok(new { Status = "AlreadyProcessed" });
        }
        // 标记为已处理
        _idempotencyService.MarkRequestAsProcessing(request.RequestId);
        try
        {
            await _processService.RunLongProcess(request);
            _idempotencyService.MarkRequestAsCompleted(request.RequestId);
            return Ok(new { Status = "Completed" });
        }
        catch (Exception ex)
        {
            _idempotencyService.MarkRequestAsFailed(request.RequestId, ex.Message);
            return StatusCode(500, new { Status = "Failed", Message = ex.Message });
        }
    }
    

4. 排查.NET中间层的重试配置

检查你的.NET项目是否用了Polly之类的重试库,不小心给这个长流程接口加了重试策略。如果有的话,要排除这个接口,或者调整重试条件(比如只在特定错误时重试,而不是超时就重试)。

总结

最推荐的是异步长流程模式,从根本上避免长时间挂起请求带来的超时、重试问题;如果暂时要维持同步模式,一定要调整代理/服务器的超时时间,关闭重试,同时加幂等校验防止重复执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:46:10