I am building a web app with different JS libraries (AngularJS, OpenLayers,...) and need a way to intercept all AJAX responses to be able, in case the logged user session expired (response gets back with 401 Unauthorized
status), to redirect him to the login page.
I know AngularJS offers interceptors
to manage such scenarios, but wasn't able to find a way to achieve such injection into OpenLayers requests. So I opted for a vanilla JS approach.
Here I found this piece of code...
(function(open) {
XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
this.addEventListener("readystatechange", function() {
console.log(this.readyState); // this one I changed
}, false);
open.call(this, method, url, async, user, pass);
};
})(XMLHttpRequest.prototype.open);
...which I adapted and looks like it behaves as expected (only tested it on last Google Chrome).
As it modifies the prototype of XMLHTTPRequest I am wondering how dangerous this could result or if it could produce serious performance issues. And by the way would there be any valid alternative?
The previous trick works ok. But what if in the same scenarion you want to inject some headers before the request gets sent? Do the following:
(function(send) {
XMLHttpRequest.prototype.send = function(data) {
// in this case I'm injecting an access token (eg. accessToken) in the request headers before it gets sent
if(accessToken) this.setRequestHeader('x-access-token', accessToken);
send.call(this, data);
};
})(XMLHttpRequest.prototype.send);
This type of function hooking is perfectly safe and is done regularly on other methods for other reasons.
And, the only performance impact is really only one extra function call for each .open()
plus whatever code you execute yourself which is probably immaterial when a networking call is involved.
In IE, this won't catch any code that tries to use the ActiveXObject
control method of doing Ajax. Well written code looks first for the XMLHttpRequest
object and uses that if available and that has been available since IE 7. But, there could be some code that uses the ActiveXObject
method if it's available which would be true through much later versions of IE.
In modern browsers, there are other ways to issue Ajax calls such as the fetch()
interface so if one is looking to hook all Ajax calls, you have to hook more than just XMLHttpRequest
.