本文介绍了拦截并更改ajax调用的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于如何拦截ajax调用并使用javascript查看其所有内容,我发现了一些有趣(可行的)答案。(和,忽略了答案2中的计时器方法。

I found some interesting (and working) answers for how to intercept an ajax call and see all of its content with javascript.(Answer1 and Answer2, ignoring the "timer approach" in answer 2).

我有一个适用于Chrome的扩展程序三分之一的页面。页面发送和接收自己的ajax请求,并主要根据接收到的数据调整自身形状。目前,我的扩展程序可以拦截并查看数据,但它不会干扰任何ajax数据。

I have a Chrome extension that works on a third's page. The page sends and receives its own ajax requests and mostly reshapes itself based on the received data. Currently, my extension can intercept and see the data received, but but it does not interfere in any of the ajax data.

现在,我想走一步并更改结果之前,页面将重塑其HTML内容!

Now I wish to go one step further and change the results before the page reshapes its HTML content!

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

User clicks a button, the page itself sends a request and receives a response with an array containing 100 elements to be displayed in a table. The page automatically creates the html table with 100 elements. Everything without my interference.

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

When the data is received, I can see the 100 elements received.

现在,我想让页面显示仅 50而不是100个元素。我该如何更改页面收到的响应?

Now let's say I want the page to show only "50" of those elements instead of 100. How could I change the response received by the page?

详细信息:


  • 页面发送请求,而不是我的扩展名(我可以更改发送的参数,但这不是最佳选择,我不想将错误的请求发送到服务器,无论如何我都无法看到或更改)。

  • 页面本身在收到响应后更改其DOM。

  • 不希望更改DOM!我需要在页面开始更改其DOM之前更改。 (接收到的数据量非常大,以致页面变得比各大洲的移动都要慢,我需要防止创建元素)

  • 页面高度动态,使用一个那些类似引导程序的每次收到响应时,都会清除并重新创建框架及其大多数DOM元素。

  • The page sends the request, not my extension (I could change the arguments sent, but that is not the best choice, I don't want to send bad requests to the server, which I cannot see or change anyhow).
  • The page itself changes its DOM after receiving the response.
  • I do not want to change the DOM! I need to change the data received before the page starts changing its DOM. (The amount of data received is so huge that the page gets slower than the movement of the continents, I need to prevent the elements from being created)
  • The page is highly dynamic, using one of those "bootstrap-like" frameworks and most of its DOM elements are cleared and recreated each time a response is received.

推荐答案

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

The important part of this method is the Object.defineProperty API.

您不能使用对象分配来覆盖 this.responseText = {...};

You can't use object assignment to override, 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>

这篇关于拦截并更改ajax调用的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 12:52