我编写了一个拦截器来获取我从服务器发送的令牌并将其添加到后续请求中:

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  constructor(private store: Store) {}
  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    return this.store.select(selectUser).pipe(
      switchMap((user) => {
        if (user && user.token) {
          const authRequest = req.clone({
            setHeaders: {
              Authorization: `Bearer ${user.token}`,
            },
          });
          return next.handle(authRequest);
        }
        return next.handle(req);
      })
    );
  }
}

根据Angular 建议,我为这个拦截器编写了一个单独的提供程序:

import { Provider } from '@angular/core';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { AuthInterceptor } from '../http-interceptors/authInterceptor';
export const authInterceptorProvider: Provider = {
  provide: HTTP_INTERCEPTORS,
  useClass: AuthInterceptor,
  multi: true,
};

然后将其提供给我的基本组件(我使用的是独立API,所以AppComponent在某种程度上是我的Main):

bootstrapApplication(AppComponent, {
  providers: [
    importProvidersFrom(HttpClientModule),
    authInterceptorProvider,
    provideState(feedFeature),
    provideState(authFeature),
    provideStore(),
    provideEffects(feedEffects, authEffects),
    provideRouter(appRoutes),
    provideHttpClient(),
    provideStoreDevtools({
      maxAge: 25,
      logOnly: !isDevMode(),
      autoPause: true,
      trace: false,
      traceLimit: 75,
    }),
  ],
});

行为是这样的,如果我删除这行:

    importProvidersFrom(HttpClientModule)

拦截器根本不工作,但我添加了它,我的浏览器在拦截器工作的情况下发出了无限的请求(我添加了一个console.log).

我判断了请求头,但也没有发送Auth头(User&amp;&amp;user.Token都存在,console.log在if语句中)

有人知道为什么要发送无限的请求吗?和/或为什么没有设置标头?

此外,我不是最好的Angular ,特别是在独立的API,我很确定我做了一些错误的事情,添加了两者:

importProvidersFrom(HttpClientModule) and provideHttpClient()

推荐答案

如果this.store.select(selectUser)正在进行API调用以获取数据,它将再次调用拦截器,从而导致无限循环.

这是奥斯卡之前解决的问题.通过使用HttpBackend进行API调用,这将在进行API调用时跳过调用拦截器.

因此,解决方案是this.store.select(selectUser)中的代码应该使用HttpBackend而不是HttpClient,这将绕过拦截器调用并防止无限循环!


而且光是provideHttpClient()就足够使用HttpClientMoudule个Provider 了!


还请注意,您也可以 Select interceptorFn,而不是为拦截器创建类的旧风格!

Angular相关问答推荐

Angular 形式验证:在空和不匹配的密码上显示错误

升级到angular 17并转换为独立的加载器拦截器后,

angular 17:app.config. server.ts中的mergeApplicationconfig导致初始化在app.config. ts中导入的提供程序

图像未显示在视图屏幕上-Angular 投影

Angular 17不接受带点(.)的路径在开发环境中,它直接抛出一个404错误

[NullInjectorError]:R3InjectorError(Standalone[_AppComponent])[]:NullInjectorError:No provider for _HttpClient

HTTP POST响应失败Angular 16

如何使用formBuilder.Group()从角形表单中删除选定的选项?

所有返回缺少权限或权限不足的FireBase项目.

Angular 12 区域环境切换器

如何在运行Angular应用程序的容器中访问Docker容器?

Angular JWT Token 被添加到lazyUpdate 而不是 HttpHeaders 中的标头

Angular:显示带有嵌套子项的内容投影

如何在Cypress 测试中切换 Angular 选项卡

angular4应用程序中输入的最小值和最大值

Angular CLI 自定义 webpack 配置

在同一个组件中使用 MatSort 的多个 mat-table

如何在Angular 4中为数字管道指定语言环境千位分隔符

在 Angular 中动态设置样式

RxJS:takeUntil() Angular 组件的 ngOnDestroy()