1

I'm making an extension that will be able to modify request responses. I did some research, found this answer https://stackoverflow.com/a/51594799/16661157 and implemented it into my extension.

When debugging this script, it detects the majority of requests but not all, unfortunately the most important for me are not. So my question is: what could be causing this?

manifest.json

{
    "manifest_version": 3,
    "permissions": [
        "tabs"
    ],
    "web_accessible_resources": [{
        "resources": ["script.js"],
        "matches": [ "<all_urls>" ]
      }],
    "action": {
        "default_popup": "index.html"
    },
    "content_scripts": [
        {
            "matches": [ "<all_urls>" ],
            "js": ["jquery-3.6.0.min.js", "contentscript.js"],
            "run_at": "document_start"
        }
    ]
}

contentscript.js

var s = document.createElement('script');
s.src = chrome.runtime.getURL('script.js');
s.onload = function() {
    this.remove();
};
(document.head || document.documentElement).appendChild(s);

script.js

var _open = XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function (method, URL) {
    var _onreadystatechange = this.onreadystatechange,
        _this = this;

    _this.onreadystatechange = function () {
        // catch only completed 'api/search/universal' requests
        try {
            console.log('Caught! :)', method, URL/*, _this.responseText*/);
        } catch (e) {}
        if (_this.readyState === 4 && _this.status === 200 && ~URL.indexOf('api/search/universal')) {
            try {
                //////////////////////////////////////
                // THIS IS ACTIONS FOR YOUR REQUEST //
                //             EXAMPLE:             //
                //////////////////////////////////////
                var data = JSON.parse(_this.responseText); // {"fields": ["a","b"]}

                if (data.fields) {
                    data.fields.push('c','d');
                }

                // rewrite responseText
                Object.defineProperty(_this, 'responseText', {value: JSON.stringify(data)});
                /////////////// END //////////////////
            } catch (e) {}

        }
        // call original callback
        if (_onreadystatechange) _onreadystatechange.apply(this, arguments);
    };

    // detect any onreadystatechange changing
    Object.defineProperty(this, "onreadystatechange", {
        get: function () {
            return _onreadystatechange;
        },
        set: function (value) {
            _onreadystatechange = value;
        }
    });

    return _open.apply(_this, arguments);
};
Mohammad
  • 571
  • 1
  • 8
  • 24
nitruseq
  • 11
  • 2
  • You need to investigate those requests in devtools and find what's different about them. Use the initiator tab of the request to see how it's made, maybe it uses `fetch` not XMLHttpRequest or maybe it's made from a worker. Maybe the site makes the request before your interceptor loads. – wOxxOm Jul 15 '22 at 05:52
  • I checked it, it uses fetch instead of xhr as you suggested. Is there any way to override fetch response? – nitruseq Jul 15 '22 at 19:09
  • https://blog.logrocket.com/intercepting-javascript-fetch-api-requests-responses/ – wOxxOm Jul 15 '22 at 20:08
  • @nitruseq did you find a way around this? I can't monkey patch the window.fetch, neither can I inject a custom fetch into the original html document. – Thomas Jungblut Sep 10 '22 at 07:44
  • yea, solution that was suggested by @wOxxOm worked fine for me. The site I was working with was using fetch instead of XMLHttpRequest – nitruseq Sep 10 '22 at 11:34

0 Answers0