我正在玩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在内部使用observable,因为它不是可观察的,所以它失败了。例如。如果您的authToken
未定义,则不返回任何内容,因此拦截方法的结果未定义。
谢谢@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