GibboK
GibboK

Reputation: 73918

How to set up a timeout and ontimeout for XMLHttpRequest?

At the moment I am using a similar code visible below to set a specific value for timeout when creating an instance of XMLHttpRequest. I also set a function for ontimeout which will be executed when event is fired.

I would like to know if it is possible to set a timeout value globally for any XMLHttpRequest and a global function when ontimeout is called.

I am aware I could use a factory for XMLHttpRequest which could set timeout and ontimeout automatically on each instance created but I would like to know if a different approach exists.

Notes: I am looking for a solution based on vanilla JavaScript (no jQuery or other libraries) and I am targeting only Chrome and FireFox latest version.

Any idea is welcome thanks.

var xhr = new XMLHttpRequest();
xhr.open('GET', '/server', true);
xhr.timeout = 2000;  
xhr.onload = function () {};   
xhr.ontimeout = function (e) {
    // do smt here
}; 
xhr.send(null);

Upvotes: 3

Views: 9331

Answers (2)

GibboK
GibboK

Reputation: 73918

I was able to monkey path XMLHttpRequest using the following code.

  (function (xhr) {
        var send = xhr.send;
        xhr.send = function (data) {
            this.timeout = 5000;
            var hasTimeOut = 'ontimeout' in this;
            if (hasTimeOut) {
                this.ontimeout = function () {
                    throw ('Error XMLHttpRequest timeout.');
                };
            }
            return send.apply(this, arguments);
        };
    })(XMLHttpRequest.prototype);

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1074208

You have at least three options:

  1. Encapsulate your use of XMLHttpRequest in your own function. That lets you apply these sorts of things in that function. The fact your code uses the function makes it perfectly clear what's going on. For instance:

    function createXHR() {
        var xhr = new XMLHttpRequest();
        xhr.timeout = 2000;  
        xhr.addEventListener("timeout", function(e) {
            // ...
        });
        return xhr;
    }
    
  2. Override XMLHttpRequest with your own version. I do not recommend doing this, but sometimes if you need to integrate with code that uses XMLHttpRequest directly, you may feel you need to do it. Example:

    (function() {
        var realXMLHttpRequest = XMLHttpRequest;
        XMLHttpRequest = function fakeXMLHttpRequest() {
            realXMLHttpRequest.apply(this, arguments);
            this.timeout = 2000;  
            this.addEventListener("timeout", function(e) {
                // ...
            });
        };
        XMLHttpRequest.prototype = realXMLHttpRequest.prototype;
    })();
    

    Again, I do not recommend it, but it's possible.

    You've said below that the one above doesn't work for you. If it doesn't, it's because the XMLHttpRequest implementation you're using is making life difficult. This workaround will work:

    (function() {
        var realXMLHttpRequest = XMLHttpRequest;
        XMLHttpRequest = function fakeXMLHttpRequest(arg) {
            var xhr;
            if (typeof arg !== "undefined") {
                // Some implementations allow for a non-standard argument, support them
                xhr = new realXMLHttpRequest(arg);
            } else {
                // Normal case
                xhr = new realXMLHttpRequest();
            }
            xhr.timeout = 2000;  
            xhr.addEventListener("timeout", function(e) {
                // ...
            });
            return xhr;
        };
        XMLHttpRequest.prototype = realXMLHttpRequest.prototype;
    })();
    

    That works even though you call it with new XMLHttpRequest because the way the new operator works is that it creates an object and calls the function with that object as this, and then the result of new is that object unless the function returns a different non-null object, as the one above does.

    Did I mention I do not recommend this? ;-)

  3. Use a library that already does #1 for you.

Upvotes: 4

Related Questions