如何拦截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
相关产品推荐
相关产品推荐

