HttpInterceptor在惰性模块中不起作用

时间:2018-11-27 20:51:41

标签: angular angular7

我已经创建了HttpInterceptor,它对于App模块可以正常工作,但是对于惰性模块的特色模块却没有调用它。我想知道为什么它不起作用。

  1. 我在HttpInterceptor中提供了app.module.ts
  2. 我正在使用Angular 7
  3. HttpClient未被使用,Http

如果您需要其他详细信息,请告诉我。

AppModule

    @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 {
  }

CoreModule

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}

];

AuthInterceptor

@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 {}

2 个答案:

答案 0 :(得分:0)

您提到您正在使用Angular 7,因此您应该在拦截器中使用pipe()而不是do()

注意:如果这不是问题,请创建一个StackBlitz演示,然后有人会从那里弄清楚

答案 1 :(得分:0)

我将检查延迟加载的模块中的所有提供程序和组件,以查看它们是否正在调用HttpClient。如果是这样,它将是HttpClient的另一个实例,而不是作为AppModule初始化的一部分构造的HttpClient实例,因此不会附加拦截器。

我可以想到几种解决方案,我的首选是B:

A)将拦截器重新连接到任何延迟加载的模块中,即:

@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中将HttpInterceptors附加到HttpClient实例。延迟加载的模块支持forRoot()单例模式,因此服务也应可用于任何延迟加载的模块。

更多关于单例https://angular.io/guide/singleton-services