Angular 拦截器根据响应路由到不同的路径
Angular Interceptor route to a different path based on response
我正在玩 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。
我该如何防止这种情况发生?我做错了什么?
此错误总是指缺少或错误的 return 值,在您的情况下,在某些时候,拦截方法不是 return 可观察的,而是什么都没有或其他东西。然后 Angular 在内部使用可观察对象,并且因为它不是可观察对象,所以它失败了。例如。如果你的 authToken
是未定义的,你 return 什么都没有,所以拦截方法的结果是未定义的。
谢谢@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();
}
}
如果有人遇到这个问题,请参考:
已接受的答案没有使用 http 拦截器,但还有另一个答案使用了拦截器
我使用的解决方案只是 return 一个使用 empty()
的空观察
我正在玩 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。
我该如何防止这种情况发生?我做错了什么?
此错误总是指缺少或错误的 return 值,在您的情况下,在某些时候,拦截方法不是 return 可观察的,而是什么都没有或其他东西。然后 Angular 在内部使用可观察对象,并且因为它不是可观察对象,所以它失败了。例如。如果你的 authToken
是未定义的,你 return 什么都没有,所以拦截方法的结果是未定义的。
谢谢@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();
}
}
如果有人遇到这个问题,请参考:
已接受的答案没有使用 http 拦截器,但还有另一个答案使用了拦截器
我使用的解决方案只是 return 一个使用 empty()