2

I'm trying to mock responses in the browser (devtools) so I patched XMLHttpRequest. This is the code I'm using to replace the responseText

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

    _this.onreadystatechange = function () {
        if (_this.readyState === 4 && _this.status === 200)) {
            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) {}

            console.log('Caught! :)', method, URL/*, _this.responseText*/);
        }
        // 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);
};

This is the easiest way I found to mock a response. But how do I create a 4XX or 5XX? I tried to replace 200 with 404 by adding the following

Object.defineProperty(_this, 'status', { value: 404 });

in various places, and even for different readyStates, but it didn't work, it was always 200. Any suggestions how I can trigger in the code above a 4XX or 5XX?

To reproduce: Copy/paste the above code in your console and execute it as follows:

var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", 'https://jsonplaceholder.typicode.com/posts/1');
oReq.send();

(StackBlitz)

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Jeanluca Scaljeri
  • 26,343
  • 56
  • 205
  • 333
  • It might not be possible (could be a native-object thing), but even if it isn't you can still reimplement everything in a wrapper object. – user202729 Feb 12 '21 at 07:12

0 Answers0