如何在发送用户请求之前注入 HTTP 请求
How to inject an HTTP request before user's request is sent
我正在学习 Angular,作为其中的一部分,我正在尝试了解如何实现我心中的 use-case。此时,我正在尝试测试服务器通信。即,RxJs 的 Observables。
我想到的 use-case 正在发送一个 POST 请求,该请求需要在服务器端接受 X-XSRF-TOKEN
header。这是第一次发送 GET 请求时作为 cookie 发送回客户端的安全 header。换句话说,与服务器的对话不能以 POST 请求开始。
我希望实现这一点的方法是包装 Angular 的 Http
class:
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.
}
}
}
所以我的问题是,我如何编写一个 POST 请求,它首先发送一个 GET 请求,等待其响应,然后发送实际的 POST 请求。当然,post
方法调用者得到的返回的Observable属于POST请求,不是GET请求。所以如果我写:
restClient.post('/', {}).subcribe(response => {
//It's POST's response
})
使用flatMap
。如果你想在触发新请求时忽略之前的请求,你可以使用 switchMap。
return get(getUrl,....)
.switchMap( response => restClient.post(url, response.token .... )
这将return调用post的Observable。
使用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
可能是一个 私有 方法,return 是一个 Observable
具有标记值的方法。这同样适用于 postToServer
,但对于 return 类型 Observable
of Reponse
。通过创建可连接的最小集中方法,您将逻辑封装成多个部分,通过将它们设为私有,您可以隐藏实现细节。
我正在学习 Angular,作为其中的一部分,我正在尝试了解如何实现我心中的 use-case。此时,我正在尝试测试服务器通信。即,RxJs 的 Observables。
我想到的 use-case 正在发送一个 POST 请求,该请求需要在服务器端接受 X-XSRF-TOKEN
header。这是第一次发送 GET 请求时作为 cookie 发送回客户端的安全 header。换句话说,与服务器的对话不能以 POST 请求开始。
我希望实现这一点的方法是包装 Angular 的 Http
class:
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.
}
}
}
所以我的问题是,我如何编写一个 POST 请求,它首先发送一个 GET 请求,等待其响应,然后发送实际的 POST 请求。当然,post
方法调用者得到的返回的Observable属于POST请求,不是GET请求。所以如果我写:
restClient.post('/', {}).subcribe(response => {
//It's POST's response
})
使用flatMap
。如果你想在触发新请求时忽略之前的请求,你可以使用 switchMap。
return get(getUrl,....)
.switchMap( response => restClient.post(url, response.token .... )
这将return调用post的Observable。
使用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
可能是一个 私有 方法,return 是一个 Observable
具有标记值的方法。这同样适用于 postToServer
,但对于 return 类型 Observable
of Reponse
。通过创建可连接的最小集中方法,您将逻辑封装成多个部分,通过将它们设为私有,您可以隐藏实现细节。