javascript - 使用http拦截器时发送重复的http请求(在Ionic 2中)

标签 javascript typescript ionic2 observable

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 模板开始的小型测试应用程序:

Test App

这清楚地显示了 Firebug 中的问题:

  • 如果使用 GET 按钮,则为第一个请求(可以,单个)。
  • 第二个请求(重复)使用“使用拦截器获取”按钮。

同时,订阅部分中的代码只执行一次,这是理所应当的。

Interceptor produces 2 http requests

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/

相关文章:

javascript - 使用 Angular 循环遍历文件夹中的所有文件/图像

带有过滤键的 Typescript 映射类型

javascript - 嵌套 Observables 在 Ionic2/Angular2 应用程序中表现不同

Typescript - 使用类的字符串名称访问类的属性

JavaScript Promise 函数返回得太早

javascript - 从 HTML 创建 JavaScript 数组

javascript - 使用 Ionic 2 配置 Identity Server 4

javascript - localForage 迭代不适用于 JS 文件

javascript - 使用 KnockoutJS 初始化后更新引导日期选择器

angular - 在 Ionic3 中自动播放的 ionic 幻灯片