jquery 自定义XMLHttpRequest.prototype.open

dsf9zpds  于 2022-12-22  发布在  jQuery
关注(0)|答案(2)|浏览(350)
var open = XMLHttpRequest.prototype.open;

XMLHttpRequest.prototype.open = function(method, uri, async, user, pass) {
    this.addEventListener("readystatechange", function(event) {  
    if(this.readyState == 4){
       var self = this;
       var response = {
         method: method,
         uri: uri,
         responseText: self.responseText
      };
      console.log(response);  
    } else {
        console.log(this.readyState);
    }
    }, false);
  open.call(this, method, uri, async, user, pass);
};

我尝试在XHR被发送之前监听它们,类似于jQuery的$.ajax方法中的beforeSend
我的目标是在发送之前监听所有的XHR。我想最接近的事情是检查上面是否有this.readyState === 1
上面的代码是否会因为我在XMLHttpRequest上使用prototype而导致jQuery之类的 AJAX 库出现故障?

46qrfjad

46qrfjad1#

我试着在他们被发送之前听XHR。
然后尝试欺骗send()方法,而不是open()方法。
上面的代码是否会因为我在XMLHttpRequest上使用prototype而导致jQuery之类的 AJAX 库出现故障?
不,不是的。只是,

  • 如果这些库选择不使用XMLHttpRequest(特别是IE),则它将不起作用
  • ...如果浏览器不支持XMLHttpRequest对象(或不支持访问或修改其原型),甚至会失败
  • libs可以通过在您之前解引用函数来绕过您的欺骗(尽管我不知道任何公共lib可以这样做)
  • 你的代码用固定数量的参数调用原生方法,不确定这是否会影响任何东西,并且它不会重新返回结果(即使我们知道它是undefined)。
krcsximq

krcsximq2#

您需要将此脚本作为DOM元素插入,但下面的代码适用于90%的网络请求:

响应拦截器.js

(function () {
  console.log('🔫 REQUEST INTERCEPTOR INJECTED');
  let CE_id = 'Your Chrome Extension ID';
  let WithNetworkPayload;
  let gotResponse = false;
  let job_network_payload = [];
  let job_network_urls = [];
    var XHR = XMLHttpRequest.prototype;
      var send = XHR.send;
      var open = XHR.open;
      XHR.open = function (method, url) {
        this.url = url; // the request url
        request_list.push({
          request: this,
          args: arguments,
        });
        job_network_urls.push(url);
        return open.apply(this, arguments);
      };
      //Get response from chosen request
      XHR.send = function () {
        this.addEventListener('load', function () {
          console.log('Got Response 🤯');
          console.log(this);
          try {
            this.response
              .text()
              .then((res) => {
                job_network_payload.push({ endpoint: this.url, payload: res });
                console.log(res);
              })
              .catch((err) => {
                job_network_payload.push({ endpoint: this.url, payload: err });
                console.log('❌ Error on getting response.Text()');
                console.log(err);
              });
          } catch (err) {
            console.log('❌ Error on getting response.Text()');
            console.log(err);
            job_network_payload.push({
              endpoint: this.url,
              payload: this.response,
            });
          }
          //sendResponsetoBackground(this.response);
        });
        return;
      };
    })();

使用通用contentScript.js将response_interceptor. js添加为DOM元素:

内容脚本.js

function inject_response_interceptor() {
  function interceptData() {
    var xhrOverrideScript = document.createElement('script');
    xhrOverrideScript.type = 'text/javascript';
    xhrOverrideScript.src = chrome.runtime.getURL(
      './injected_scripts/response_interceptor.js'
    );
    document.head.prepend(xhrOverrideScript);
  }

  let interval = setInterval(() => {
    if (document.head) {
      clearInterval(interval);
      interceptData();
    }
  }, 100);
}
inject_response_interceptor();

在清单中,不要忘记添加要在documentStart注入的contentScript.js:

清单.js

...
"content_scripts": [{
      "matches": ["http://*/*", "*://*/*"],
      "run_at": "document_start",
      "js": ["contentScript.js"]
    }]

相关问题