TL;DR;
为什么在 http 拦截器中订阅 Observable 会向服务器产生重复的 http 请求?
示例代码:
doGetWithInterceptor() {
console.log("Http get with interceptor -> 2 http calls ?? Why?");
this.http_interceptor_get("http://ip.jsontest.com/").subscribe(data => {
console.log("But only one block of data received:", data);
this.result= data.ip;
});
}
http_interceptor_get(url : string) {
let req= this.http.get(url).map(res => res.json());
req.subscribe((data) => {
console.log("[HttpInterceptor]");
});
return req;
}
完整详细信息:
我在 Ionic 2 项目中使用 http 拦截器服务来全局检测错误、身份验证等...
但是这样做时,我发现对服务器有重复的 http 请求。
我有一个从空白的 Ionic 2 模板开始的小型测试应用程序:
这清楚地显示了 Firebug 中的问题:
- 如果使用 GET 按钮,则为第一个请求(可以,单个)。
- 第二个请求(重复)使用“使用拦截器获取”按钮。
同时,订阅部分中的代码只执行一次,这是理所应当的。
home.ts代码如下:
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
result : string = "???";
constructor(public navCtrl: NavController, public http: Http) {
}
http_get(url : string) {
return this.http.get(url).map(res => res.json());
}
http_interceptor_get(url : string) {
let req= this.http.get(url).map(res => res.json());
req.subscribe((data) => {
console.log("[HttpInterceptor]");
});
return req;
}
doGet() {
console.log("Normal http get -> 1 http call");
this.http_get("http://ip.jsontest.com/").subscribe(data => {
console.log("One block of data received:", data);
this.result= data.ip;
});
}
doGetWithInterceptor() {
console.log("Http get with interceptor -> 2 http calls ?? Why?");
this.http_interceptor_get("http://ip.jsontest.com/").subscribe(data => {
console.log("But only one block of data received:", data);
this.result= data.ip;
});
}
doClearResult() {
this.result= "???";
}
}
最佳答案
因为你并没有真正拦截。您只需订阅该请求两次。
http_interceptor_get(url : string) {
let req= this.http.get(url).map(res => res.json());
req.subscribe((data) => { //1st subscription - 1st call
console.log("[HttpInterceptor]");
});
return req; //return original request
}
然后您将在 doGetWithInterceptor()
中再次订阅您的 http 请求。
如果您想记录通话详细信息,可以使用do()
。
http_interceptor_get(url : string) {
//return http call
return this.http.get(url).map(res => res.json())
.do(data=>{
//do checks.
return data; //be sure to return data so it is passed on to subscription.
});
}
然后调用您的doGetWithInterceptor()
关于javascript - 使用http拦截器时发送重复的http请求(在Ionic 2中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41763483/