0

I followed the first set of instructions here to create an extension that can intercept XHR requests. I got it to work correctly and am successfully using it to read xhr requests, but unfortunately the requests I actually care about use fetch instead of xhr, so I'm just intercepting a bunch of calls to https://n.clarity.ms/collect.

I have three files in my Chrome extension that you are probably interested in. First is scripts/xhrOverride.js

(function() {
var XHR = XMLHttpRequest.prototype;
var send = XHR.send;
var open = XHR.open;
XHR.open = function(method, url) {
    this.url = url; // the request url
    return open.apply(this, arguments);
}
XHR.send = function() {
    this.addEventListener('load', function() {
        console.log(this.url);
        if (this.url.includes(FOO)) {
            var dataDOMElement = document.createElement('div');
            dataDOMElement.id = '__interceptedData';
            dataDOMElement.innerText = this.response;
            dataDOMElement.style.height = 0;
            dataDOMElement.style.overflow = 'hidden';
            document.body.appendChild(dataDOMElement);
        }               
    });
    return send.apply(this, arguments);
};
})();

Second is manifest.json

{
  "manifest_version": 3,
  "name": "BAR",
  "version": "0.0.1",
  "content_security_policy": {
    "extension_pages": "script-src 'self'; object-src 'self'"
  },
  "description": "Attempt to port BAR to a chrome extension.",

  "icons": {
    "16": "images/icon-16.png",
    "32": "images/icon-32.png",
    "48": "images/icon-48.png",
    "128": "images/icon-128.png"
  },
  "host_permissions": [
    "http://localhost/*"
  ],
  "content_scripts": [
    {
      "js": [
        "third-party/jquery.min.js",
        "scripts/content.js"
      ],
      "run_at": "document_start",
      "matches": [
        FOO
      ]
    }
  ],
  "web_accessible_resources": [
    {
      "resources": ["scripts/xhrOverride.js"],
      "matches": ["<all_urls>"]
    }
  ]
}

And finally is my scripts/content.js

var loop = 0;
function dowork() {
    const refresh = document.querySelectorAll('div');
    for (let i=0; i < refresh.length; i++) {
      // TODO Filter more
      if (refresh[i].innerHTML.includes("Refresh")) {
        refresh[i].click();
      }
    }
}

function interceptData() {
    var xhrOverrideScript = document.createElement('script');
    xhrOverrideScript.src = chrome.runtime.getURL('scripts/xhrOverride.js');
    xhrOverrideScript.onload = function() {
        this.remove();
    };
    document.head.prepend(xhrOverrideScript);
}

function checkForDOM() {
  if (document.body && document.head) {
    interceptData();
  } else {
    requestIdleCallback(checkForDOM);
  }
}
requestIdleCallback(checkForDOM);

function scrapeData() {
    var responseContainingEle = document.getElementById('__interceptedData');
    if (responseContainingEle) {
        throw new Error('Success!');
        var response = JSON.parse(responseContainingEle.innerHTML);
        $.post('http://localhost:5151/', response);
    } else {
        requestIdleCallback(scrapeData);
    }
}
requestIdleCallback(scrapeData);

var checkInterval = setInterval(()=>{
  loop = loop + 1;
  dowork();
},10000  /**  time in milliseconds        **/);

What is the minimal changes necessary to get this to work for fetch requests instead of XHR requests? What is the optimal way to do that? My ultimate goal is to read the responses from fetch requests sent to an API at a specific URL (and forward that data to a service on localhost) since that might be unclear. Thanks in advance.

Joshua Snider
  • 705
  • 1
  • 8
  • 34
  • 2
    You can use one of the [existing interceptors](https://www.google.com/search?q=intercept+window.fetch) for `window.fetch` (as well as various methods in `Response.prototype`). Also note that using web_accessible_resources is unreliable because it misses early requests, see [this answer](/a/72607832) that shows a reliable solution. – wOxxOm Feb 01 '23 at 01:14

0 Answers0