拦截的XHR-在增加负载之前运行功能 [英] Intercepted XHR - run function before raising load

查看:118
本文介绍了拦截的XHR-在增加负载之前运行功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在带有扩展名注入的自定义XMLHttpRequest类的网页上,在文档的其余部分引发load事件之前,我需要 拦截和修改某些响应.现在,我的修改代码对load事件做出了反应.在触发load事件之前,我将如何使用函数来修改响应?

On a web page with a extension-injected custom XMLHttpRequest class, I need to intercept and modify certain responses before the load event is raised on the rest of the document. Right now, my modification code reacts to the load event. How would I use a function to modify the response before the load event was fired?

这是我正在使用的代码:

This is the code I am using:

let oldXHROpen = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function (method, url, async, user, password) {
    var originalresp = this;
    //Do something with the method, url and etc.
    originalresp.addEventListener('load', async function () {
        //Do something with the response text
        //***This function needs to execute before load is raised for the rest of the document***
        value = '<note><body>This is a test XML document.</body></note>';
        parser = new DOMParser();
        apiresponsexml = parser.parseFromString(value, 'application/xml');
        //Replace data in the response
        Object.defineProperties(originalresp, {
            'response': {
                value: value
            },
            'responseXML': {
                value: apiresponsexml,
            },
            'responseText': {
                value: value,
            }
        });
    });
    return oldXHROpen.apply(originalresp, arguments);
};

此问题是上一个线程的延续 a>.

This question is a continuation of this previous thread.

推荐答案

send()内部覆盖onreadystatechange(在加载/加载之前触发):

Override onreadystatechange (fired before load/onload) inside send():

function plantXhrHook() {
  let origStateChange;

  function modifyResponse(e) {
    if (this.readyState === 4) {
      const value = 'foo';
      let xml;
      Object.defineProperties(this, {
        response: {value},
        responseText: {value},
        responseXML: {
          get() {
            if (typeof xml === 'undefined')
              xml = new DOMParser().parseFromString(value, 'application/xml');
            return xml;
          },
        },
      });
    }
    if (origStateChange) {
      origStateChange.apply(this, arguments);
    }
  };

  const origSend = XMLHttpRequest.prototype.send;
  XMLHttpRequest.prototype.send = function () {
    origStateChange = this.onreadystatechange;
    this.onreadystatechange = modifyResponse;
    origSend.apply(this, arguments);
  };
}

const script = document.createElement('script');
script.textContent = `(${plantXhrHook})()`;
document.documentElement.appendChild(script);
script.remove();

由于其他扩展程序或页面脚本也可能会钩住XHR,因此使用"run_at":"document_start" .

Since other extensions or page scripts may also hook XHR, it would make sense to run your code in a content script with "run_at": "document_start".

这篇关于拦截的XHR-在增加负载之前运行功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆