Angular Interceptor根据响应路由到不同的路径

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

我正在玩Angular拦截器,如果响应状态是401,我想重新路由,下面是我尝试过的。

@Injectable()
export class AuthInterceptorService implements HttpInterceptor {

  constructor(private _localStorageService: LocalStorageService, private _router: Router, private _location: Location) { }


  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (req.url.includes("/login")) {
      return next.handle(req);
    }
    let authToken: LocalStorage = this._localStorageService.getItem('auth-token');
    if (authToken) {
      return next.handle(
        req.clone({
          headers: req.headers.append('Authorization', 'jwt ' + authToken.value)
        })
      ).pipe(tap((response: HttpResponse<any>) => {
        console.log(response);
        if (response instanceof HttpResponse) {
          if (response.body.status == 401) {
            this._router.navigate([Routes.LOGIN]);
            return response;
          }
        }
      }));
    }
    this._router.navigate(['/login']);
  }
}

这个过程是有效的,但每当路由发生变化时,我都会在chrome dev控制台中得到这个:错误你提供了'undefined'来预期流。您可以提供Observable,Promise,Array或Iterable。

我该如何防止这种情况?我做错了什么?

angular angular-http-interceptors
2个回答
2
投票

此错误总是指丢失或错误的返回值,在您的情况下,在某些时候,拦截方法不会返回可观察但不返回任何内容或其他内容。然后Angular在内部使用observable,因为它不是可观察的,所以它失败了。例如。如果您的authToken未定义,则不返回任何内容,因此拦截方法的结果未定义。


0
投票

谢谢@Julien指点我正确的方向。在看了答案后,我更多地寻找解决方案,以下是对我有用的解决方案

@Injectable()
export class AuthInterceptorService implements HttpInterceptor {

  constructor(private _localStorageService: LocalStorageService, private _router: Router, private _location: Location) { }


  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (req.url.includes("/login")) {
      return next.handle(req);
    }
    let authToken: LocalStorage = this._localStorageService.getItem('auth-token');
    if (authToken) {
      return next.handle(
        req.clone({
          headers: req.headers.append('Authorization', 'jwt ' + authToken.value)
        })
      ).pipe(tap((response: HttpResponse<any>) => {
        console.log(response);
        if (response instanceof HttpResponse) {
          if (response.body.status == 401) {
            this._router.navigate([Routes.LOGIN]);
            return response;
          }
        }
      }));
    }
    this._router.navigate(['/login']);
    return empty();
  }
}

如果有人遇到这个问题,请参阅:Angluar2 routing inside http interceptor

接受的答案不使用http拦截器,但有另一个使用拦截器的答案

我使用的解决方案是使用empty()返回一个空的observable

© www.soinside.com 2019 - 2024. All rights reserved.