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

AspNetBoilerplate的Angular4项目中Chrome DevTools重复请求原因

重复POST请求问题排查:AspNetBoilerplate + Angular 4 + NSwag

先看你提供的NSwag生成的请求代码:

userApplyLimitAsync(): Observable<GetUserApplyLimitOutput> { 
  let url_ = this.baseUrl + "/api/services/app/AElfApplication/UserApplyLimitAsync"; 
  url_ = url_.replace(/[?&]$/, ""); 
  let options_ = { 
    method: "post", 
    headers: new Headers({ "Content-Type": "application/json", "Accept": "application/json" }) 
  }; 
  return this.http.request(url_, options_).flatMap((response_) => { 
    return this.processUserApplyLimitAsync(response_); 
  }).catch((response_: any) => { 
    if (response_ instanceof Response) { 
      try { 
        return this.processUserApplyLimitAsync(response_); 
      } catch (e) { 
        return <Observable<GetUserApplyLimitOutput>><any>Observable.throw(e); 
      } 
    } else return <Observable<GetUserApplyLimitOutput>><any>Observable.throw(response_); 
  }); 
} 

protected processUserApplyLimitAsync(response: Response): Observable<GetUserApplyLimitOutput> { 
  const status = response.status; 
  let _headers: any = response.headers ? response.headers.toJSON() : {}; 
  if (status === 200) { 
    const _responseText = response.text(); 
    let result200: any = null; 
    let resultData200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver); 
    result200 = resultData200 ? GetUserApplyLimitOutput.fromJS(resultData200) : new GetUserApplyLimitOutput(); 
    return Observable.of(result200); 
  } else if (status !== 200 && status !== 204) { 
    const _responseText = response.text(); 
    return throwException("An unexpected server error occurred.", status, _responseText, _headers); 
  } 
  return Observable.of<GetUserApplyLimitOutput>(<any>null); 
}

以及调用代码:

this._withdrawService.userApplyLimitAsync() 
  .subscribe((result) => { 
    this.withdrawActive = result.isSucceed; 
  });

结合你的开发场景,我整理了几个最可能导致两次相同POST请求的原因,按排查优先级排序:

1. 组件/服务中重复调用了userApplyLimitAsync()

这是最常见的触发原因。比如你的组件ngOnInit钩子被触发了两次(路由配置重复、组件在模板中被重复渲染),或者这段订阅代码被放在了会重复执行的逻辑里(比如ngOnChanges中且触发频繁)。

排查方法:在userApplyLimitAsync()方法第一行加个日志:

console.log('userApplyLimitAsync 被调用了');

如果控制台打印两次,说明方法被调用了两次,去追踪调用它的代码为什么执行多次。

2. Observable被重复订阅

Angular的HTTP请求返回的是冷Observable——每一次订阅都会发起一次全新的请求。即使你只写了一次.subscribe(),如果这个Observable被其他地方(比如模板里的async管道、另一段业务代码)额外订阅了,就会触发两次请求。

排查方法:

  • 检查组件模板有没有用async管道绑定这个方法返回的Observable(比如*ngIf="(_withdrawService.userApplyLimitAsync() | async) as result")
  • 在return this.http.request(url_, options_)前加日志:
    console.log('发起HTTP请求');
    
    如果打印两次但userApplyLimitAsync只打印一次,说明Observable被重复订阅了。

3. AspNetBoilerplate的Token自动刷新机制导致

AspNetBoilerplate的Angular客户端内置了AbpHttpInterceptor,当请求携带的AccessToken过期时,拦截器会自动刷新Token,然后重新发起原请求。这就会出现两次请求:第一次是带过期Token的请求(通常返回401),第二次是带新Token的正常请求(返回200)。

排查方法:查看Network面板中两次请求的响应状态码,如果第一次是401,第二次是200,那就是这个原因——这是ABP框架的正常行为,用于自动处理Token过期,不需要额外修改。

4. NSwag生成代码的异常处理逻辑(可能性低)

看你提供的代码,catch块里会对Response类型的错误再次调用processUserApplyLimitAsync,但这个逻辑是处理响应内容,不会发起新请求。除非第一次请求返回非200/204状态码,这个逻辑会解析响应并抛出异常,但只会是一次请求的两次处理,不会出现两次POST请求,所以这个可能性很低。

快速排查步骤总结

  1. 先确认userApplyLimitAsync()是否被调用两次;
  2. 再确认HTTP请求是否被发起两次(排除重复订阅);
  3. 最后检查请求的响应状态码,判断是否是Token刷新导致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:59:51