【问题标题】:Resend request angular 2重新发送请求角度 2
【发布时间】:2016-05-18 17:39:44
【问题描述】:

在 Angular 2 应用程序中,对 API 的每个请求都有带有令牌的标头,以防令牌过期,API 会以 401 http 代码响应。我有一种更新令牌的方法,但是如何在获取新令牌的过程中重新发送先前的请求以暂停其他请求?

【问题讨论】:

    标签: angular rxjs5 angular2-http


    【解决方案1】:

    您可以通过这种方式扩展 Http 类,使用 observables 的 catch 运算符捕获错误:

    一种方法可能是扩展 HTTP 对象以拦截错误:

    @Injectable()
    export class CustomHttp extends Http {
      constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) {
        super(backend, defaultOptions);
      }
    
      request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
        console.log('request...');
        return super.request(url, options).catch(res => {
          // do something
        });        
      }
    
      get(url: string, options?: RequestOptionsArgs): Observable<Response> {
        console.log('get...');
        return super.get(url, options).catch(res => {
          // do something
        });
      }
    }
    

    并按如下所述进行注册:

    bootstrap(AppComponent, [HTTP_PROVIDERS,
        new Provider(Http, {
          useFactory: (backend: XHRBackend, defaultOptions: RequestOptions) => new CustomHttp(backend, defaultOptions),
          deps: [XHRBackend, RequestOptions]
      })
    ]);
    

    catch 运算符中定义的回调中,您可以调用您的方法来更新令牌、获取结果、在源请求上设置新令牌并再次执行它。这将是完全透明的。

    这是一个示例:

    get(url: string, options?: RequestOptionsArgs): Observable<Response> {
        return super.get(url, options).catch(res => {
          if (res.status === 401) {
            return this.getToken().flatMap(token => {
              var sourceOptions = options || {};
              var headers = sourceOptions.headers || new Headers();
              headers.append('Authorization', token); // for example
              return super.get(url, options);
            });
          }
    
          return Observable.throw(res);
        });
      }
    

    编辑

    要“暂停”其他请求,您需要使用 doshare 运算符在 getToken 方法中实现一些缓存:

    getToken() {
      if (hasTokenExpired()) {
        this.token = null;
        this.tokenObservable = null;
      }
    
      if (this.token) {
        // Gotten the new token
        return Observable.of(this.token);
      } else if (this.tokenObservable) {
        // Request in progress...
        return this.tokenObservable;
      } else {
        // Execute the "refresh token" request
        return this.get('/refreshToken')
          .map(res => res.json)
          .do(token => {
            this.token = token;
            this.tokenObservable = null;
          })
          .share();
      }
    }
    

    【讨论】:

    • 谢谢,我如何在获取新令牌时暂停其他请求?
    • 不客气!我会在getToken 方法中实现一些缓存。我相应地更新了我的答案......
    • 你在示例中使用了哪个版本的 rxjs?
    猜你喜欢
    • 2016-11-01
    • 2015-02-21
    • 1970-01-01
    • 1970-01-01
    • 2018-02-19
    • 2019-09-25
    • 1970-01-01
    • 1970-01-01
    • 2019-12-04
    相关资源
    最近更新 更多