[英]Angular HTTP interceptor error not refreshing view
我正在关注本教程https://angular-academy.com/angular-jwt/并且我的 HTTP 拦截器 class 需要一点帮助。
当我在 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)
这是我的 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));
}));
}
}
所以,这里我们再次 go。
抛出该错误是因为如果错误为401
(如果我从您的第一篇文章中没记错的话),您没有在您的intercept()
方法中返回可观察的对象。
您不应该在拦截器中手动订阅。 Angular 为您做到这一点。 您需要使用诸如 switchMap 之类的switchMap
运算符返回一个可观察对象。 对于副作用,请使用tap
运算符。
删除订阅后您的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));
}));
}
}
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);
}
}));
}
在 next.handle 之后尝试 Remove.subscribe(r => r) 调用。 您需要返回可观察的,而不是 function 调用。
return next.handle(
this.addToken(request, token.token)
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.