Angular HTTP拦截器错误,无法刷新视图

问题描述 投票:0回答:1

我正在按照这个教程 https:/angular-academy.comangular-jwt。 我的HTTP拦截器类需要一点帮助。

当我在401(Unauthorized error)后成功刷新token时,代码重试HTTP调用,我得到了OK,但视图和订阅没有更新,有时我得到以下错误。

core.js:9110 ERROR TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
   at subscribeTo (subscribeTo.js:27)
   at subscribeToResult (subscribeToResult.js:11)
   at CatchSubscriber.error (catchError.js:38)
   at XMLHttpRequest.onLoad (http.js:1974)
   at ZoneDelegate.invokeTask (zone-evergreen.js:391)
   at Object.onInvokeTask (core.js:34182)
   at ZoneDelegate.invokeTask (zone-evergreen.js:390)
   at Zone.runTask (zone-evergreen.js:168)
   at ZoneTask.invokeTask [as invoke] (zone-evergreen.js:465)
   at invokeTask (zone-evergreen.js:1603) (editado) 

这是我的401处理程序。

private handle401Error(request: HttpRequest<any>, next: HttpHandler,tokens) {
  if (!this.isRefreshing) {
    this.isRefreshing = true;
    this.refreshTokenSubject.next(null);
    return this.auth.refreshToken(tokens).pipe(
      switchMap((token: any) => {
        this.isRefreshing = false;
        this.refreshTokenSubject.next(token.token);
        this.db.removeAll('token');
        this.db.storage.set('token',token);
        return next.handle(this.addToken(request, token.token));
      })).subscribe(r => r);
  } else {
    return this.refreshTokenSubject.pipe(
      filter(token => token != null),
      take(1),
      switchMap(jwt => {
        console.log(jwt)
        return next.handle(this.addToken(request, jwt));
      }));
  }
}
angular ionic4
1个回答
0
投票

所以,我们又来了。

抛出这个错误是因为你没有在你的 intercept() 方法,如果错误是 401 如果我没记错的话,你的第一个帖子)。

你不应该在拦截器中手动订阅。Angular已经为你做了。你需要使用 RxJS 运算符来返回一个可观察的对象,例如 switchMap. 副作用使用 tap 运营商。

您的 handle401Error 删除订阅后应。

private handle401Error(request: HttpRequest<any>, next: HttpHandler,tokens) {
    if (!this.isRefreshing) {
      this.isRefreshing = true;
      this.refreshTokenSubject.next(null);

      return this.auth.refreshToken(tokens).pipe(
        switchMap((token: any) => {
          this.isRefreshing = false;
          this.refreshTokenSubject.next(token.token);
          this.db.removeAll('token');
          this.db.storage.set('token',token);

          return next.handle(this.addToken(request, token.token));
        }));
    } else {

      // I'm not sure about this part since to me it seems that in this block the 
      // subject it will always emit null value after the token expires and the
      // browser is refreshed because the data won't persist.
      // if I'm right use this here and should work: **return next.handle(request);**
      return this.refreshTokenSubject.pipe(
        filter(token => token != null),
        take(1),
        switchMap(jwt => {
          console.log(jwt)
          return next.handle(this.addToken(request, jwt));
        }));
    }
  }

这个... intercept 方法,删除 next.handle 后的 .subscribe(r => r) 调用。

 intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    if (this.authService.getJwtToken()) {
      request = this.addToken(request, this.authService.getJwtToken());
    }

    return next.handle(request).pipe(catchError(error => {
      if (error instanceof HttpErrorResponse && error.status === 401) {
        // here don't forget tor return
        return this.handle401Error(request, next);
      } else {
        return throwError(error);
      }
    }));
  }

0
投票

试着在 next.handle 之后删除 .subscribe(r => r) 的调用。你需要返回observable,而不是函数调用。

return next.handle(
    this.addToken(request, token.token)
);
© www.soinside.com 2019 - 2024. All rights reserved.