简体   繁体   English

Angular HTTP 拦截器错误未刷新视图

[英]Angular HTTP interceptor error not refreshing view

I am following this tutorial https://angular-academy.com/angular-jwt/ and I need a little help with my HTTP interceptor class.我正在关注本教程https://angular-academy.com/angular-jwt/并且我的 HTTP 拦截器 class 需要一点帮助。

When I successfully refresh the token after 401 (Unauthorized error), the code retry the HTTP call and I get the OK back but the view and subscription isn't updating and I sometime get the following error:当我在 401(未经授权的错误)之后成功刷新令牌时,代码重试 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) 

This is my 401 handler:这是我的 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));
      }));
  }
}

So, here we go again.所以,这里我们再次 go。

That error is thrown because you aren't returning an observable in your intercept() method if the error is 401 (if I remember correctly from your first post).抛出该错误是因为如果错误为401 (如果我从您的第一篇文章中没记错的话),您没有在您的intercept()方法中返回可观察的对象。

You should not manually subscribe in the interceptor.您不应该在拦截器中手动订阅。 Angular does that for you. Angular 为您做到这一点。 You need to return an observable instead, using RxJS operators like switchMap .您需要使用诸如 switchMap 之类的switchMap运算符返回一个可观察对象。 For side effects use the tap operator.对于副作用,请使用tap运算符。

Your handle401Error after removing the subscription should be:删除订阅后您的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));
        }));
    }
  }

The intercept method: intercept方法:

 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);
      }
    }));
  }

Try Remove.subscribe(r => r) call after next.handle.在 next.handle 之后尝试 Remove.subscribe(r => r) 调用。 You need to return observable, not function call.您需要返回可观察的,而不是 function 调用。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM