Angular 15:如何让HttpInterceptor仅为部分请求添加授权?
可以通过以下几种实用方案实现部分请求跳过授权头添加:
方案一:在拦截器中过滤目标URL
直接在拦截器内判断请求URL是否属于无需授权的第三方服务(比如谷歌地图API),匹配则跳过授权头添加逻辑。
import { Injectable } from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http'; import { Observable } from 'rxjs'; @Injectable() export class AuthInterceptor implements HttpInterceptor { intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { // 定义不需要授权的域名/路径列表 const excludedDomains = ['maps.googleapis.com']; // 检查当前请求是否命中排除规则 const shouldSkip = excludedDomains.some(domain => request.url.includes(domain)); if (shouldSkip) { return next.handle(request); } // 给需要授权的请求添加Bearer令牌 const authToken = localStorage.getItem('authToken'); // 替换为你的token获取逻辑 const authorizedRequest = request.clone({ setHeaders: { Authorization: `Bearer ${authToken}` } }); return next.handle(authorizedRequest); } }
方案二:通过自定义请求头标记跳过拦截
发送请求时添加自定义头标记,拦截器检测到标记后跳过授权处理,同时移除该自定义头避免传递给目标服务器。
发送请求时添加标记
import { HttpClient, HttpHeaders } from '@angular/common/http'; // 在组件/服务中发送谷歌地图请求 constructor(private http: HttpClient) {} fetchGoogleMapsData() { const headers = new HttpHeaders().set('Skip-Authorization', 'true'); return this.http.get('https://maps.googleapis.com/maps/api/...', { headers }); }
拦截器中处理标记
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { // 检查是否存在跳过授权的标记 if (request.headers.has('Skip-Authorization')) { // 移除自定义标记头,避免发送到第三方服务 const cleanedRequest = request.clone({ headers: request.headers.delete('Skip-Authorization') }); return next.handle(cleanedRequest); } // 正常添加授权头逻辑 const authToken = localStorage.getItem('authToken'); const authorizedRequest = request.clone({ setHeaders: { Authorization: `Bearer ${authToken}` } }); return next.handle(authorizedRequest); }
方案三:创建独立的无拦截器HttpClient实例
如果存在大量无需授权的请求,可以创建不绑定全局拦截器的HttpClient实例,专门用于这类请求。
import { Injectable, Injector } from '@angular/core'; import { HttpClient, HttpHandler } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class NoAuthHttpClient { public readonly http: HttpClient; constructor(injector: Injector) { // 获取原始HttpHandler,不经过任何拦截器 const originalHandler = injector.get(HttpHandler); this.http = new HttpClient(originalHandler); } }
使用该实例发送请求
import { NoAuthHttpClient } from './no-auth-http-client.service'; constructor(private noAuthHttp: NoAuthHttpClient) {} getGoogleMapsData() { return this.noAuthHttp.http.get('https://maps.googleapis.com/maps/api/...'); }
方案选择建议
- 仅少数固定第三方服务:优先选方案一,逻辑简单易维护;
- 需要灵活控制单个请求:选方案二;
- 大量独立无授权请求:选方案三更高效。
内容的提问来源于stack exchange,提问作者dave0688
相关产品推荐
相关产品推荐

