【问题标题】:Intercept AND CHANGE the results of an ajax call [closed]拦截并更改ajax调用的结果[关闭]
【发布时间】:2015-10-29 13:31:19
【问题描述】:

关于如何拦截 ajax 调用并使用 javascript 查看其所有内容,我找到了一些有趣(且有效)的答案。(Answer1Answer2,忽略答案 2 中的“计时器方法”)。

我有一个可以在第三方页面上运行的 Chrome 扩展程序。页面发送和接收自己的 ajax 请求,并且主要根据接收到的数据重新调整自身。目前,我的扩展程序可以拦截并查看接收到的数据,但不会干扰任何 ajax 数据。

现在我希望更进一步,更改结果页面重塑其 HTML 内容之前!

示例:

用户点击一个按钮,页面本身发送一个请求并接收一个包含 100 个要在表格中显示的元素的数组的响应。该页面会自动创建包含 100 个元素的 html 表格。一切都没有我的干涉。

接收到数据后,可以看到接收到的100个元素。

现在假设我希望页面只显示“50”个元素而不是 100 个。如何更改页面收到的响应?

详情:

  • 页面发送请求,而不是我的扩展(我可以更改发送的参数,但这不是最佳选择,我不想向服务器发送错误的请求,我无论如何都看不到或更改)。
  • 页面本身在收到响应后会更改其 DOM。
  • 不想更改 DOM!我需要在页面开始更改其 DOM 之前更改收到的数据。 (接收到的数据量太大,页面的移动速度比大陆的移动还要慢,我需要阻止创建元素)
  • 该页面是高度动态的,使用其中一种“类似引导”的框架,并且每次收到响应时都会清除并重新创建其大部分 DOM 元素。

【问题讨论】:

标签: javascript html ajax google-chrome-extension dom-events


【解决方案1】:

这个方法的重要部分是Object.defineProperty API。

你不能使用对象赋值来覆盖,this.responseText = {...};

<button>send</button>

<script>
  const nativeOpen = XMLHttpRequest.prototype.open;
  const nativeSend = XMLHttpRequest.prototype.send;

  const proxiedOpen = function () {
    // Mount the URL that needs to be intercepted to the `XMLHttpRequest` object.
    if (arguments[1].includes('jsonplaceholder.typicode.com/todos/1')) this._url = arguments[1];
    nativeOpen.apply(this, arguments);
  };

  const proxiedSend = async function () {
    if (this._url) {
      // Make other requests, it can also be a fixed value.
      const data = await fetch('https://jsonplaceholder.typicode.com/todos/5').then(res => res.json());
      // The data of `todos/1` is rewritten as `todos/5`
      Object.defineProperty(this, 'responseText', { value: JSON.stringify(data), writable: false });
    }
    nativeSend.apply(this, arguments);
  };

  // Override native methods
  XMLHttpRequest.prototype.open = proxiedOpen;
  XMLHttpRequest.prototype.send = proxiedSend;

  document.querySelector('button').addEventListener('click', () => {
    const xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function () {
      if (this.readyState == 4 && this.status == 200) {
        console.log(this.responseText); // Will get the data of `todos/5` instead of `todos/1`.
      }
    };
    xhttp.open('GET', 'https://jsonplaceholder.typicode.com/todos/1', true);
    xhttp.send();
  });
</script>

【讨论】:

    猜你喜欢
    • 2011-10-16
    • 1970-01-01
    • 2010-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-24
    • 1970-01-01
    相关资源
    最近更新 更多