【问题标题】:Intercepted XHR - run function before raising load拦截 XHR - 在提高负载之前运行函数
【发布时间】:2019-03-21 13:28:01
【问题描述】:

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

这是我正在使用的代码:

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);
};

这个问题是this previous thread的延续。

【问题讨论】:

    标签: javascript html google-chrome-extension xmlhttprequest


    【解决方案1】:

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

    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" 的内容脚本中运行您的代码是有意义的。

    【讨论】:

    • 谢谢!当我有更多时间添加其他代码时,我会尝试一下。
    猜你喜欢
    • 2019-06-30
    • 2016-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多