Angular 11中HTTP拦截器误应用于同级模块问题
解决Angular中CoreModule拦截器影响TranslationModule资源请求的问题
这个问题的核心在于Angular的HttpClient是单例模式——当你在根注入器(比如被AppModule导入的CoreModule,属于根层级)中添加HTTP拦截器后,所有注入的HttpClient实例都会自动应用这些拦截器,包括TranslationLoader里的那个。
既然你不想用拦截器里加条件判断的临时方案,那最干净的解决方式是给TranslationModule提供一个独立的、不携带全局拦截器的HttpClient实例。具体做法如下:
步骤1:修改TranslationModule,提供独立的HttpClient
我们可以利用HttpBackend(HttpClient的底层请求处理器)来创建一个全新的HttpClient实例,这个实例不会继承根注入器里的任何拦截器。
更新后的TranslationModule代码如下:
import { NgModule } from '@angular/core'; import { HttpClient, HttpBackend } from '@angular/common/http'; import { TranslocoModule, TRANSLOCO_CONFIG, translocoConfig, TRANSLOCO_LOADER } from '@ngneat/transloco'; import { environment } from '../environments/environment'; import { Translation } from '@ngneat/transloco'; @Injectable({ providedIn: 'root' }) export class TranslationLoader implements TranslocoLoader { constructor(private http: HttpClient) {} getTranslation(lang: string) { return this.http.get<Translation>(`/assets/i18n/${lang}.json`); } } @NgModule({ declarations: [], // 移除HttpClientModule,避免和自定义的HttpClient提供器冲突 imports: [TranslocoModule], providers: [ // 提供不携带全局拦截器的HttpClient实例 { provide: HttpClient, useFactory: (handler: HttpBackend) => new HttpClient(handler), deps: [HttpBackend] }, { provide: TRANSLOCO_CONFIG, useValue: translocoConfig({ availableLangs: ['en-US', 'de-CH', 'fr-CH', 'it-CH'], defaultLang: 'en-US', reRenderOnLangChange: true, prodMode: environment.production }) }, { provide: TRANSLOCO_LOADER, useClass: TranslationLoader } ] }) export class TranslationModule {}
为什么这个方案有效?
HttpBackend是Angular处理HTTP请求的底层服务,它不会应用任何HTTP_INTERCEPTORS。- 我们通过工厂函数创建了一个全新的
HttpClient实例,直接依赖HttpBackend,完全绕过了根注入器中带拦截器的HttpClient单例。 - 因为这个HttpClient是在TranslationModule的providers里定义的,所以只有该模块内(包括TranslationLoader)注入的HttpClient会使用这个实例,全局的API请求依然会使用带拦截器的根HttpClient。
额外注意事项
- 确保TranslationModule中不再导入
HttpClientModule,否则会和我们自定义的HttpClient提供器产生冲突。 - 如果你后续有其他不需要拦截器的本地资源请求,也可以复用这个模块内的HttpClient实例。
内容的提问来源于stack exchange,提问作者Robin
相关产品推荐
相关产品推荐

