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

如何拦截FetchBackend的fetch请求以添加授权头?

拦截FetchBackend的Fetch请求添加授权头方案

HttpInterceptor确实仅对HttpClient发起的请求生效,而FetchBackend直接调用原生fetch API,所以需要通过以下两种方式实现拦截并添加授权头:

方案一:自定义FetchBackend(Angular专属)

继承Angular原生的FetchBackend,重写其handle方法,在处理请求前注入授权头:

import { Injectable } from '@angular/core';
import { FetchBackend, HttpRequest, HttpResponse, HttpErrorResponse } from '@angular/common/http';
import { Observable, from } from 'rxjs';
import { map, catchError } from 'rxjs/operators';

@Injectable()
export class CustomFetchBackend extends FetchBackend {
  override handle(req: HttpRequest<any>): Observable<HttpResponse<any>> {
    // 克隆请求并添加授权头
    const authToken = localStorage.getItem('auth_token');
    const authReq = authToken 
      ? req.clone({ setHeaders: { Authorization: `Bearer ${authToken}` } })
      : req;

    // 调用原生fetch处理请求,转换为Observable
    return from(fetch(authReq.url, {
      method: authReq.method,
      headers: authReq.headers,
      body: authReq.body,
      credentials: 'include' // 根据业务需求调整是否携带凭证
    })).pipe(
      map(async (rawRes) => {
        // 解析响应体,兼容非JSON格式
        const body = await rawRes.json().catch(() => rawRes.text().catch(() => null));
        return new HttpResponse({
          body,
          status: rawRes.status,
          statusText: rawRes.statusText,
          headers: rawRes.headers,
          url: rawRes.url || ''
        });
      }),
      catchError((err) => {
        throw new HttpErrorResponse({
          error: err,
          status: err.status || 0,
          statusText: err.statusText || 'Unknown Error',
          url: req.url
        });
      })
    );
  }
}

然后在根模块中替换原生的FetchBackend:

import { NgModule } from '@angular/core';
import { HttpClientModule, FetchBackend } from '@angular/common/http';
import { CustomFetchBackend } from './custom-fetch-backend';

@NgModule({
  imports: [HttpClientModule],
  providers: [
    { provide: FetchBackend, useClass: CustomFetchBackend }
  ]
})
export class AppModule { }

优点:仅拦截Angular通过FetchBackend发起的请求,不会影响页面内其他fetch调用;完全贴合Angular的HTTP体系。
缺点:需要维护自定义Backend,Angular版本更新时需注意兼容性。

方案二:全局重写原生fetch(全局生效)

直接覆盖浏览器的原生fetch方法,对所有fetch请求统一添加授权头:

// 在应用初始化时执行(比如app.component.ts的ngOnInit,或单独的初始化服务)
const originalFetch = window.fetch;

window.fetch = async (input: RequestInfo | URL, init?: RequestInit) => {
  const authToken = localStorage.getItem('auth_token');
  const requestHeaders = new Headers(init?.headers);

  // 添加授权头(仅当存在token时)
  if (authToken) {
    requestHeaders.set('Authorization', `Bearer ${authToken}`);
  }

  // 调用原生fetch并返回结果
  return originalFetch(input, {
    ...init,
    headers: requestHeaders
  });
};

优点:实现简单,无需修改Angular的HTTP配置;所有页面内的fetch请求都会被拦截(包括第三方脚本发起的)。
缺点:影响范围广,可能干扰其他依赖原生fetch的逻辑;不属于Angular体系内的方案,调试时需注意全局副作用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 19:32:46