Angular 14中Http请求被调用两次的问题求助
解决API请求触发两次的问题
以下是几种常见原因和对应的解决方式:
1. 重试操作符导致重复请求
你的基础服务中使用了retry(1)操作符,它的作用是当请求失败时自动重试1次,这会导致失败场景下总共发送2次请求。如果你的请求实际成功但仍出现两次请求,需注意retry(n)表示最多重试n次,总请求数为n+1次。
解决办法:
如果不需要重试机制,直接移除retry(1):
public getCall(url: any): any { return this.http.get<any>(url, this.httpOptions).pipe(catchError(this.handleError)); }
如果需要保留重试,可添加条件判断,仅在特定错误时重试,比如:
import { retryWhen, delay, take } from 'rxjs/operators'; // 仅重试1次,间隔1秒 public getCall(url: any): any { return this.http.get<any>(url, this.httpOptions).pipe( retryWhen(errors => errors.pipe(delay(1000), take(1))), catchError(this.handleError) ); }
2. 重复订阅Observable
Observable是“冷”流,每次订阅都会触发一次新请求。如果代码中存在多次订阅同一个Observable的情况(比如同时在组件代码和模板async管道中订阅,或在多个生命周期钩子中调用订阅方法),就会导致多次请求。
解决办法:
- 检查组件代码,确保只订阅一次;
- 在服务层将Observable转为多播类型,使用
shareReplay()让多个订阅共享同一次请求结果:
import { shareReplay } from 'rxjs/operators'; public getNotificationsCounts(token: any) { return this.baseService.getCall(this.url.SALES_MANAGER_NOTIFICATIONS_COUNT + token).pipe(shareReplay(1)); }
3. 模板绑定触发重复执行
如果组件模板中直接调用返回Observable的方法(比如<div>{{ getNotificationsCounts(token) | async }}</div>),Angular的变更检测会多次执行该方法,每次执行都会创建新的Observable并触发请求。
解决办法:
在组件初始化时完成订阅,将结果存入变量,模板直接使用变量:
// 组件代码 ngOnInit() { this.salesManagerService.getNotificationsCounts(token).subscribe((response: any) => { if(response.response.status){ this.notifications = response; } }); }
<!-- 模板代码 --> <div *ngIf="notifications">{{ notifications | json }}</div>
4. 浏览器跨域预检请求
浏览器发送跨域请求时,会先发送一次OPTIONS预检请求,确认服务器允许跨域后再发送实际业务请求。这种情况下Network面板会显示两次请求,但OPTIONS是浏览器自动发起的预检,不属于重复业务请求。
解决办法:
这是正常的跨域机制,无需额外处理,只需确保后端配置了正确的CORS规则,允许前端域名的请求。
内容的提问来源于stack exchange,提问作者Mukesh Verma
相关产品推荐
相关产品推荐

