我需要对REST服务进行连续的http调用,但是每个调用都在调用头中使用唯一的有效令牌,所以如果我有一些组件同时初始化它们正在“获取” “同时使用相同的令牌调用,因此我需要修改我的get函数以进行一次调用,等待响应,从该响应中获取新令牌并在下次调用中使用它等等接下来的电话。
我的自定义http服务
@Injectable()
export class HttpCustomService {
token: string;
activeRequestsSubject = new BehaviorSubject<number>(0);
constructor(private httpClient: HttpClient,
private authService: AuthService) {
this.authService.token$.subscribe(
token => this.token = token
);
}
getHeaders( withToken: boolean) {
let headers = new HttpHeaders({'Content-Type': 'application/json;
charset=UTF-8', 'Cache-Control': 'no-cache', 'Pragma': 'no-cache' });
if (withToken) {
headers = new HttpHeaders({'Content-Type': 'application/json; charset=UTF-8',
'Authorization': `Bearer ${this.token}`,
'Cache-Control': 'no-cache', 'Pragma': 'no-cache'} );
}
return headers;
}
get(url: string, withToken: boolean): Observable<any> {
this.loadingSubject.next(true);
const options = {
headers: this.getHeaders(withToken)
};
this.incrementActiveRequest();
return this.httpClient.request('get', url, options).do(
response => {
if (response.body && response.body.token) {
this.authService.setToken(response.body.token);
}
this.loadingSubject.next(false);
this.decrementActiveRequest();
},
error => {this.loadingSubject.next(false);
this.decrementActiveRequest();
});
}
这些是我如何使用该服务的示例
getQuotes(): Observable<any> {
return this.httpCustom.get(`${this.urlBase}/quotes`, true)
.map((response: any) => {
return response.body.result;
}).catch(err => {
this.handleError(err);
return Observable.of(null);
});
}
getPolicies(): Observable<any> {
return this.httpCustom.get(`${this.urlBase}/policies`, true)
.map((response: any) => {
return response.body.result;
}).catch(err => {
this.handleError(err);
return Observable.of(null);
});
}
我想我必须使用flatMap,但我不知道如何在我的“get”方法中使用它。有什么想法吗?
答案 0 :(得分:0)
我可能误解了,但认为变化很小
每次通话都使用唯一的有效令牌
所以你不想在构造函数中使用它,
constructor(private ...) {
this.authService.token$.subscribe(token => this.token = token);
}
你想在每次获取时先做到这一点,
get(url...) {
this.authService.token$.map(token => {
const headers = this.getHeaders(token);
...
this.httpClient.request(...)
});
}
如果是单次拍摄,你需要在authService中保存令牌吗?
另外,我认为上面activeRequestsSubject
与loadingSubject
修改强>
在OP发表评论后进行更正 - 将this.authService.token$.subscribe
更改为this.authService.token$.map
。
答案 1 :(得分:0)
我显然找到了解决方案。感谢所有评论,他们都以某种方式帮助了我。
我的新方法:
get(url: string): Observable<any> {
if (this.activeRequestsSubject.value === 0) {
this.incrementActiveRequest();
const headers = {headers: new HttpHeaders({'Content-Type': 'application/json; charset=UTF-8',
'Authorization': `Bearer ${this.token}`,
'Cache-Control': 'no-cache',
'Pragma': 'no-cache'})};
return this.httpClient.request('get', url, headers)
.do(res => {
this.decrementActiveRequest();
this.authService.setToken(res['token']);
return res; });
}else {
this.incrementActiveRequest();
return this.authService.token$.skip(this.activeRequestsSubject.value - 2).first().mergeMap(
(token: string) => {
const headers = {headers: new HttpHeaders({'Content-Type': 'application/json; charset=UTF-8',
'Authorization': `Bearer ${token}`,
'Cache-Control': 'no-cache',
'Pragma': 'no-cache'})};
return this.httpClient.request('get', url, headers).do(res => {
this.decrementActiveRequest();
this.authService.setToken(res['token']);
return res; });
}
);
}
}