如何在发送用户请求之前注入HTTP请求

时间:2017-06-18 21:12:02

标签: angular rxjs angular2-http

我正在学习Angular,作为其中的一部分,我试图看看如何实现我想到的用例。此时,我正在尝试测试服务器通信。即,RxJs的Observables。

我想到的用例是发送一个POST请求,要求在服务器端接受X-XSRF-TOKEN标头。这是第一次发送GET请求时作为cookie发送回客户端的安全标头。换句话说,没有与服务器的对话可以从POST请求开始。

我希望实现这一点的方法是包装Angular的Http类:

import {Http, RequestOptions, RequestOptionsArgs, Response} from '@angular/http';
import { Injectable} from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { CookieService } from 'angular2-cookie/services/cookies.service';

@Injectable()
export class RestClient {
  private static xsrfTokenCookie: string = 'XSRF-TOKEN';
  private static xsrfTokenHeader: string = 'X-XSRF-TOKEN';
  private static xsrfToken: string = null;

  constructor(private http: Http, private cookies: CookieService) {}

  get(url: string, options?: RequestOptionsArgs): Observable<Response> {
    return this.http.get(url, options);
  }

  post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
    if (!options) {
      options = new RequestOptions(new Headers());
    }
    if (!RestClient.xsrfToken) {
      RestClient.xsrfToken = this.cookies.get(RestClient.xsrfTokenCookie);
    }
    if (!RestClient.xsrfToken) {
      //TODO: Somehow construct an Observable object which once subscribed, it will make a GET request
      // then using the returned cookie, it will construct the actual POST request.
    }
  }
}

所以我的问题是,如何编写一个首先发送GET请求的POST请求,等待其响应,然后它将发送实际的POST请求。当然,post方法的调用者将获得的返回的Observable属于POST请求,而不属于GET请求。所以,如果我写:

restClient.post('/', {}).subcribe(response => {
  //It's POST's response
})

2 个答案:

答案 0 :(得分:1)

使用flatMap。如果您想在触发新请求时忽略先前的请求,可以使用switchMap。

return get(getUrl,....)
   .switchMap( response => restClient.post(url, response.token .... )

这将返回后调用的Observable。

答案 1 :(得分:1)

使用mergeMap

    post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
        if (!options) {
          options = new RequestOptions(new Headers());
        }
        if (!RestClient.xsrfToken) {
          RestClient.xsrfToken = this.cookies.get(RestClient.xsrfTokenCookie);
        }
        if (!RestClient.xsrfToken) {
          return this.getToken(...)
                 .mergeMap(token => this.postToServer(...));
        }
      }
    }

在这种情况下,getToken可以是私有方法,该方法返回带有令牌值的Observable。这同样适用于postToServer,但返回类型ObservableReponse。通过创建可连接的最小聚焦方法,您可以将逻辑封装成碎片,并通过将它们设为私有来隐藏实现细节。