Set a breakpoint in XHR in Chrome

Viewed 21602

I have a page that sends an XHR request when a form is submitted and I would like to get Chrome to break when it receives a response. It seems like the best way to accomplish this would be if Chrome has a javascript function that I can call that breaks execution but I've been unable to find anything like that so far. Is there another solution?

Edit:

I don't actually have a callback defined for the request so I can't set a breakpoint that way. The request is being sent with this line of jquery code:

$.post(this.action, $(this).serialize(), null, "script");

where this is a form element. The null argument is where you would usually define a callback but with the "script" argument, raw javascript is returned by the server and then directly executed, so it seems the only way to break and step through the code is with the debugger; statement. This works, but when stepping through the code you can't actually see which line you are on so its a little awkward. I suspect that this is a limitation of Chrome's debugging tools.

5 Answers

For me the solution was to use Initiator tab in the Network panel, it showed me the script that sent the request

ES6+

XMLHttpRequest = (Parent =>
    class XMLHttpRequest extends Parent {
        constructor() {
            const onload = () => {
                this.removeEventListener('load', onload);
                debugger;
            };
            super(...arguments);
            this.addEventListener('load', onload);
        }
    }
)(XMLHttpRequest);

ES5

XMLHttpRequest = (function (Parent) {
    XMLHttpRequest.prototype = Parent;

    return XMLHttpRequest;

    function XMLHttpRequest() {
        var self = this;
        Parent.apply(this, arguments);
        this.addEventListener('load', function () {
            self.removeEventListener('load', onload);
            debugger;
        });
    }
})(XMLHttpRequest);

This should let you inspect the request/response in the Network developer tool.

Note 01

ES5 syntax IS NOT to be understood as ES5+ mainly because function extends class ... isn't something that works at runtime. The class part will fail with Uncaught TypeError: Failed to construct 'XMLHttpRequest': Please use the 'new' operator. At that point, you may consider changing :

Parent.apply(this, arguments);

into

super(...arguments);

Note 02

Every solution here supposes that the library that issue the XHR request did not cache the XMLHttpRequest constructor [yet].

Note 03

The above code does not work with ES5 especially b/c of supper vs. .prototype inheritance syntax.

In order to circumvent thes issues, one may tap into the prototype. In the following code, I choosed to tap into the the xhr.send method.

ES5+

XMLHttpRequest.prototype.send = (function (send) {
    return function () {
        this.addEventListener('load', function onload() {
            this.removeEventListener('load', onload);
            debugger;
        });

        return send.apply(this, arguments);
    };
})(XMLHttpRequest.prototype.send);

That said, the latter code didn't work for the issue that had me dig into this... Mainly because the internal Angular code registered an event listener (that fully redirects the browser) before even calling the xhr.send method. Not great, eh !?

That's it!

Related