如何在HTTP拦截器的请求重试机制中设置自定义请求头?
解决重试请求添加自定义请求头的问题
你的问题核心在于retryWhen里的tap操作符仅处理副作用,无法替换重试的请求实例。要实现重试时添加自定义请求头,需要在错误流中返回修改后的请求处理流,具体调整如下:
- 在拦截器函数内部初始化重试计数器,避免全局变量污染
- 将
tap替换为concatMap(或mergeMap),以此在错误发生时返回新的请求处理流 - 每次重试前克隆原始请求,添加
X-Retry-Count头后再发起请求
修改后的完整代码:
intercept(req: HttpRequest<any>, next: HttpHandler) { let count = 0; const RETRY_COUNT = 3; // 可根据需求调整重试次数 return next.handle(req).pipe( timeout(30000), retryWhen((errors) => errors.pipe( filter((error) => !(error instanceof ProgressEvent)), concatMap((error) => { count++; if (count > RETRY_COUNT) { // 超过重试次数,抛出错误进入catchError return throwError(() => error); } else { // 克隆请求并添加重试计数头 const newReq = req.clone({ headers: req.headers.set('X-Retry-Count', count.toString()) }); // 返回修改后的请求处理流,作为重试的新请求 return of(newReq).pipe(delay(2000)); } }) ) ), catchError((error) => { // 记录错误逻辑 console.error('请求最终失败:', error); return throwError(() => error); }) ); }
关键说明:
concatMap负责将错误事件转换为新的请求流,确保重试时发送的是添加了自定义头的newReq- 计数器
count随每次错误递增,保证重试请求头的计数准确 - 超过重试次数时,用
throwError终止重试流程,进入catchError处理最终错误
内容的提问来源于stack exchange,提问作者Sparda
相关产品推荐
相关产品推荐

