重试Observable之前在HTTP上更改标头

VGe*_*iev 5 observable rxjs typescript angular

我在前端使用TypeScript的Angular 2。我正在尝试实现在每个请求上设置授权标头的http拦截器。如果访问令牌过期,我正在尝试重试该请求,请在重试之前使用带有刷新令牌的新访问令牌并更改当前请求的标头。

如何在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());
        }
    });
}
}
Run Code Online (Sandbox Code Playgroud)

n00*_*dl3 3

我会使用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());
}
Run Code Online (Sandbox Code Playgroud)

另请注意,使用类似状态this.defaultOptions可能不是您的最佳选择,使用可观察会更合适。