【发布时间】:2021-03-07 13:20:10
【问题描述】:
我创建了一个拦截器来添加身份验证令牌并在身份验证令牌过期时刷新,如下所示:
@Injectable()
export class CustomInterceptors implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// ... implementation details
}
}
我已经在 angular (app.module) 的主模块中注册了这个拦截器,如下所示:
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
RouterModule.forRoot(appRoutes),
HttpClientModule,
MatSnackBarModule,
// Fuse modules
FuseModule.forRoot(fuseConfig),
FuseProgressBarModule,
FuseSidebarModule,
FuseThemeOptionsModule,
// App modules
LayoutModule,
LightboxModule
],
bootstrap: [
AppComponent
],
providers: [AuthGuard, UsersService, ErrorService, {
provide: HTTP_INTERCEPTORS,
useClass: CustomInterceptors,
multi: true
}]
})
export class AppModule {
}
我有两个延迟加载的模块 AModule 和 BModule,如下所示:
-- AModule
const routes: Routes = [
{
path: '**',
component: AComponent,
resolve: {
interventions: AService
}
}
];
@NgModule({
declarations: [
AComponent
],
imports: [
RouterModule.forChild(routes),
MatButtonModule,
MatCheckboxModule,
MatDatepickerModule,
MatFormFieldModule,
MatIconModule,
MatInputModule,
MatMenuModule,
MatRippleModule,
MatTableModule,
MatToolbarModule,
MatSelectModule,
MatSnackBarModule,
MatSortModule,
MatTooltipModule,
TranslateModule.forChild(),
MatProgressSpinnerModule,
MatPaginatorModule,
FuseSharedModule,
FuseConfirmDialogModule,
FuseSidebarModule,
FuseDeleteInfoModule
],
providers: [
AsService
]
})
export class AModule {
}
--------------------------------------------------------------------
--BModule
const routes: Routes = [
{
path: '**',
component: BComponent,
resolve: {
contacts: BService
}
},
];
@NgModule({
declarations: [
BComponent
],
imports: [
RouterModule.forChild(routes),
MatButtonModule,
MatCheckboxModule,
MatExpansionModule,
MatDatepickerModule,
MatFormFieldModule,
MatIconModule,
MatInputModule,
MatMenuModule,
MatRippleModule,
MatTableModule,
MatToolbarModule,
MatProgressSpinnerModule,
MatAutocompleteModule,
FuseSharedModule,
MatTabsModule,
FuseConfirmDialogModule,
FuseSidebarModule,
MatSelectModule,
MatSnackBarModule,
MatChipsModule,
MatTableExporterModule,
MatSortModule,
MatTooltipModule,
TranslateModule.forChild(),
MatPaginatorModule,
MatRadioModule,
MatListModule,
MatExpansionModule,
MatSidenavModule,
MatCardModule,
ReactiveFormsModule,
FormsModule,
GalleryModule,
LightboxModule,
],
providers: [
BService,
// {
// provide: HTTP_INTERCEPTORS,
// useClass: CustomInterceptors,
// multi: true
// }
]
})
export class BModule {
}
两个延迟加载模块的路由如下:
{
path: 'A',
loadChildren: './a/a.module#AModule',
canActivate: [AuthGuard],
data: { roles: ['Administrator', 'Supervisor','Operator']}
},
{
path: 'B',
loadChildren: './b/b.module#BModule',
canActivate: [AuthGuard],
data: { roles: ['Administrator']}
}
问题是拦截器对来自 BModule 的调用不起作用,但它对 AModule 的调用成功。
我找到了一个解决方法,在 BModule 的提供程序部分添加拦截器。这是不对的,因为我基本上是在 BModule 中实例化拦截器的另一个对象。我想让 app.module 中声明的拦截器在所有延迟加载的模块之间共享。
对于解决此问题的任何帮助或指导,我将不胜感激。
问候, 兰多。
附言
另一个正在工作的延迟加载模块(让我们称为 C 模块)在有人提交一些更改时像 B 模块一样崩溃。我运行了git diff 来查看导致模块停止工作的差异。结果如下:
const routes: Routes = [
@@ -134,7 +138,10 @@ const routes: Routes = [
MatCardModule,
ReactiveFormsModule,
MatListModule,
- FormsModule
+ FormsModule,
+ GalleryModule,
+ LightboxModule,
+ ImageGalleryModule
],
providers: [
CService,
我做了一些测试,我能够确定拦截器将停止为导入 ImageGalleryModule 的模块工作。以下是ImageGalleryModule:
@NgModule({
declarations: [
ImageGalleryComponent
],
imports: [
MatButtonModule,
MatCheckboxModule,
MatDatepickerModule,
MatFormFieldModule,
MatIconModule,
MatInputModule,
MatMenuModule,
MatRippleModule,
MatTableModule,
MatToolbarModule,
MatTableExporterModule,
MatSnackBarModule,
MatSortModule,
TranslateModule.forChild(),
MatPaginatorModule,
MatTooltipModule,
MatProgressSpinnerModule,
FuseSharedModule,
FuseConfirmDialogModule,
FuseSidebarModule,
MatSelectModule,
MatRadioModule,
MatListModule,
MatExpansionModule,
MatSidenavModule,
MatChipsModule,
MatTabsModule,
MatCardModule,
MatTooltipModule,
MatAutocompleteModule,
FormsModule,
ReactiveFormsModule,
GalleryModule,
LightboxModule,
],
providers: [
DatePipe,
],
exports:[
ImageGalleryComponent
]
})
export class ImageGalleryModule {
}
奇怪的是,导入此模块会导致拦截器无法工作,因为此模块不会导入或导出 HttpClientModule。
【问题讨论】:
-
您是否有 stackblitz 或其他要测试的东西?从我所见,您可以拦截所有 http 调用
-
forRootmoduleWithProviders 方法应该可以帮到你。 -
@RandoShtishi 您必须在
SharedModule/CoreModule中创建 forRoot 方法,并在导入此模块时使用ShareModule.forRoot()方法。并确保forRoot方法具有providers: [InterceptorService]。检查forRootdocs,那里提到的几乎所有内容 -
@RandoShtishi 在这种情况下,请确保您仅在
AppModule中导入了HttpClientModule.. -
@RandoShtishi 无论如何,几乎所有时间
CoreModule/ShareModule都会被导入到功能模块中,所以你只需要调用forRoot方法。不知道你在这里看到了什么错误。
标签: javascript angular typescript angular-http-interceptors