Angular配置HttpInterceptor后HttpClient重复调用API问题
我在Angular独立式应用中设置了HttpInterceptor,用于给请求头添加ApiToken:
export const authInterceptor: HttpInterceptorFn = (req, next) => { console.log('authInterceptor'); console.log('request', req.method, req.url); req = req.clone({ setHeaders: { ApiToken: '*****************************', }, }); return next(req); };
并在app.config.ts中引入该拦截器:
export const appConfig: ApplicationConfig = { providers: [ provideRouter(routes), provideHttpClient(withInterceptors([authInterceptor])), { provide: ApiConfiguration, useValue: { rootUrl: 'http://localhost:5042' } }, provideServiceWorker('ngsw-worker.js', { enabled: !isDevMode(), registrationStrategy: 'registerWhenStable:30000', }), ], };
通过main.ts以独立式方式启动应用:
bootstrapApplication(AppComponent, appConfig) .catch((err) => console.error(err));
目前遇到的问题:HttpClient会重复调用API两次——第一次请求不带ApiToken请求头(未经过拦截器处理),第二次才携带该请求头。如果将provideHttpClient(withInterceptors([authInterceptor]))替换为provideHttpClient(),拦截器不会触发,API也仅被调用一次。怀疑问题出在拦截器或Angular调用拦截器的逻辑上,求解决建议。
排查重复提供HttpClient的情况:
确认项目中是否有其他位置(比如组件、其他模块的providers)重复调用provideHttpClient(),这会导致多个HttpClient实例共存,其中一个未绑定拦截器,发起无token的请求,另一个经过拦截器处理发起带token的请求。检查请求触发源:
查看组件或服务中是否不小心重复订阅了同一个Observable请求(比如多次调用.subscribe()却未共享订阅),或者有两处同时发起了同一个API请求,其中一处的发起时机早于拦截器初始化完成。临时禁用Service Worker验证:
你配置了Service Worker,可以先将provideServiceWorker中的enabled设为false,验证是否是Service Worker的缓存策略导致请求重复或重发。细化拦截器日志排查:
在拦截器中添加更详细的日志(比如打印req.headers),同时在请求发起的位置也添加日志,对比两次请求的调用栈,确认第一次请求是否真的未经过拦截器,还是拦截器执行了但未正确设置请求头。用
HttpContext标记跳过拦截的请求:
如果存在不需要拦截器处理的请求,可以通过HttpContext标记,在拦截器中跳过这些请求,避免重复处理导致的请求重复:// 定义上下文token export const SKIP_AUTH = new HttpContextToken(() => false); // 发起请求时添加上下文 this.http.get('/api/data', { context: new HttpContext().set(SKIP_AUTH, true) }); // 拦截器中判断处理 export const authInterceptor: HttpInterceptorFn = (req, next) => { if (req.context.get(SKIP_AUTH)) { return next(req); } // 原有添加ApiToken的逻辑 req = req.clone({ setHeaders: { ApiToken: '*****************************', }, }); return next(req); };
内容的提问来源于stack exchange,提问作者mattinsalto

