角拦截器根据响应路由到其他路径

时间:2019-02-19 10:43:09

标签: angular angular-http-interceptors

我正在使用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开发者控制台中获取此消息:错误您在需要流的地方提供了“ undefined”。您可以提供一个Observable,Promise,Array或Iterable。

如何防止这种情况?而我在做什么错呢?

2 个答案:

答案 0 :(得分:2)

此错误始终表示缺少返回值或错误的返回值,在您的情况下,在某些情况下,intercept方法不会返回可观察到的值,而是什么都不返回或返回其他值。然后,可观察对象由Angular内部使用,并且由于它不是可观察对象,因此失败。例如。如果您的authToken未定义,则不返回任何内容,所以intercept方法的结果也未定义。

答案 1 :(得分: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()

返回一个可观察的空值