angular - HttpInterceptor 在惰性模块中不起作用
问题描述
我已经创建了HttpInterceptor
适用于 App 模块的应用程序模块,但是它不会被作为惰性模块的特色模块调用。我想知道为什么它不起作用。
- 我已经提供了
HttpInterceptor
inapp.module.ts
。 - 我正在使用 Angular 7
HttpClient
正在使用的不是Http
.
如果您需要其他详细信息,请告诉我。
应用模块
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
BrowserAnimationsModule,
HttpClientModule,
AppRoutingModule,
NgbModule.forRoot(),
ThemeModule.forRoot(),
CoreModule.forRoot(),
],
bootstrap: [AppComponent],
providers: [
{provide: APP_BASE_HREF, useValue: '/'},
AuthGuard,
{
provide: NbRoleProvider,
useClass: RoleProvider,
},
ZtLoaderService
],
})
export class AppModule {
}
核心模块
export class CoreModule {
constructor(@Optional() @SkipSelf() parentModule: CoreModule) {
throwIfAlreadyLoaded(parentModule, 'CoreModule');
}
static forRoot(): ModuleWithProviders {
return <ModuleWithProviders> {
ngModule: CoreModule,
providers: [
...NB_CORE_PROVIDERS,
httpInterceptorProviders
],
};
}
}
httpInterceptorProviders
export const httpInterceptorProviders = [
{provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true},
{provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true}
];
身份验证拦截器
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private injector: Injector) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// do not intercept request whose urls are filtered by the injected filter
console.log("intercept.........................");
this.authService.isAuthenticatedOrRefresh().subscribe(response=>{
console.log("authenticated ----------->", response);
})
return this.authService.isAuthenticatedOrRefresh()
.pipe(
switchMap(authenticated => {
if (authenticated) {
return this.authService.getToken().pipe(
switchMap((token: any) => {
const JWT = `Bearer ${token.getValue()}`;
req = req.clone({
setHeaders: {
Authorization: JWT,
},
});
return next.handle(req);
}),
)
} else {
// Request is sent to server without authentication so that the client code
// receives the 401/403 error and can act as desired ('session expired', redirect to login, aso)
return next.handle(req);
}
}),
)
}
protected get authService(): NbAuthService {
return this.injector.get(NbAuthService);
}
}
惰性模块:BPOEntryModule
@NgModule({
imports: [
ThemeModule,
BPORoutingModule,
Ng2SmartTableModule
],
declarations: [
...routedComponents,
BlListEntry,
EntryListSearchResultComponent,
EntryListSearchComponent,
ModalComponent,
ResultItemComponent,
ResultToolbarComponent
],
entryComponents: [ModalComponent],
providers: [BPOEntryService]
})
export class BPOEntryModule {}
解决方案
我会检查延迟加载模块中的所有提供程序和组件,看看它们是否正在调用 HttpClient。如果它们是,这将是 HttpClient 的一个不同实例,而不是作为 AppModule 初始化的一部分构造的实例,因此不会附加拦截器。
我能想到几个解决方案,我的偏好是 B:
A) 在任何延迟加载的模块 IE 中重新附加拦截器:
@NgModule({
imports: [
ThemeModule,
BPORoutingModule,
Ng2SmartTableModule
],
declarations: [
...routedComponents,
BlListEntry,
EntryListSearchResultComponent,
EntryListSearchComponent,
ModalComponent,
ResultItemComponent,
ResultToolbarComponent
],
entryComponents: [ModalComponent],
providers: [
BPOEntryService,
httpInterceptorProviders
]
})
export class BPOEntryModule {}
B) 把所有依赖HttpClient的服务都放到CoreModule里面(或者为http服务新建一个模块,并创建一个forRoot方法)。您现有的核心模块是如何编写的,它使用 forRoot 命令创建一个依赖服务的单例:
CoreModule.forRoot(),
由于它们是与您的 AppModule 一起作为单例创建的,因此它们应该将 AppModule 中的 HttpInterceptor 附加到 HttpClient 实例。延迟加载的模块支持 forRoot() 单例模式,因此这些服务也应该可用于任何延迟加载的模块。
在这里阅读更多关于单身人士https://angular.io/guide/singleton-services
推荐阅读
- c# - 如何将图像或超链接添加到 TeamCity 测试失败报告或/和构建日志?
- angular - WebStorm 没有设置环境变量
- javascript - ES6 GroupBy 2 或更多
- vba - 在 Excel VBA 中运行相同的代码两次时无法获取 OLEObjects 属性错误
- mysql-workbench - 如何确定 MySQL Workbench 中的当前分隔符?
- php - Vue.js 和 Laravel - 将 vuejs 与 laravel 集成后不显示图像
- python-2.7 - Caffe2/detectron infer_simple 没有检测到任何物体
- vue.js - 如何动态更改 vuetify 菜单的方向
- websocket - 使用消息间放气更好的 websocket 压缩
- postgresql - 如何将值从表 A 复制到 B 并在 A 中插入对 B 的引用?