我在前端使用带有 TypeScript 的 Angular 2。我正在尝试实现一个 http 拦截器,它在每个请求上设置授权 header 。如果访问 token 过期,我将尝试重试请求,在重试之前使用刷新 token 获取新的访问 token 并更改当前请求的 header 。
如何在 retryWhen 算子中更新请求头?
例如这里是 HttpInterceptor:
export class HttpInterceptor extends Http {
get(url: string, options?: RequestOptionsArgs): Observable<Response> {
return super.get(url, this.setRequestAuthorizationHeader(options)).retryWhen((errors: any) => this.errorHandler(errors));
}
private setRequestAuthorizationHeader(options?: RequestOptionsArgs): RequestOptionsArgs {
// some checks
// get accessToken from localStorage
options.headers.append('Authorization', 'Bearer ' + accessToken);
}
private errorHandler(errors) {
return errors.switchMap((err) => {
if (err.status === 401) {
let closedSubject = new Subject();
this.authenticationService.refreshToken()
.subscribe(data => {
// How to update authorization header? This doesn't work.
this.defaultOptions.headers.append('Authorization', 'Bearer ' + data.accessToken);
closedSubject.next();
});
return <any>closedSubject;
}
else {
return Observable.throw(err.json());
}
});
}
}
最佳答案
我会使用 catch
而不是 retryWhen
因为后者会重播相同的可观察对象,并且参数已经设置。
顺便说一句,您的主题在 errorHanlder
中毫无用处:
export class HttpInterceptor extends Http {
get(url: string, options ? : RequestOptionsArgs): Observable < Response > {
return super.get(url, this.setRequestAuthorizationHeader(options)).catch(errors => this.errorHandler(errors, url, options))
});
}
private setRequestAuthorizationHeader(options ? : RequestOptionsArgs): RequestOptionsArgs {
// some checks
// get accessToken from localStorage
options.headers.append('Authorization', 'Bearer ' + accessToken);
return options
}
private errorHandler(err: any, url: string, options ? : RequestOptionsArgs) {
if (err.status === 401) {
return this.authenticationService.refreshToken()
.switchMap(data => {
// save accessToken to localStorage
return super.get(url, this.setRequestAuthorizationHeader(options));
});
}
return Observable.throw(err.json());
}
另请注意,使用像 this.defaultOptions
这样的状态可能不是您的最佳选择,使用 anobservable 会更合适。
关于angular - 在重试 Observable 之前更改 HTTP header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43277943/