Reputation: 73918
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
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
Reputation: 1074208
You have at least three options:
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;
}
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? ;-)
Use a library that already does #1 for you.
Upvotes: 4