If the AJAX request was initiated by jquery $.ajax
, by default you can use jquery's global AJAX event handlers to monitor Ajax events, but I am encountering Ajax requests originating from native JavaScript, So this approach won't work.
Then, there are other methods, such as Pub/sub, but this request of the JS code I can not change, there is no add to the code publish problem. Similarly, JQuery .bind
and .trigger
also cannot be used.
Finally, you decide to use direct override XMLHttpRequest
, while cooperating with custom events.
Search on the StackOverflow, found that a crooked nuts gave an unreliable solution, well, posted to everyone to see:
;(function () {var open = window. XMLHttpRequest.prototype.open, send = window.
XMLHttpRequest.prototype.send, onreadystatechange;
function Openreplacement (method, URL, async, user, password) {//Some the Code return open.apply (this, arguments); } function sendreplacement (data) {//some code if (this.onreadystatechange) This._onreadystatechange = This.onrea
Dystatechange;
This.onreadystatechange = onreadystatechangereplacement;
Return send.apply (this, arguments); function Onreadystatechangereplacement () {//some code if (This._onreadystatechange) return this._onreadystate
Change.apply (this, arguments); } window.
XMLHttpRequest.prototype.open = openreplacement; Window.
XMLHttpRequest.prototype.send = sendreplacement;
})();
This solution cannot listen to all of XHR Events
them, and the readystatechange
event is send
not monitored until the method is invoked, and the event cannot be heard readyState = 1
. At the same time, if you use the send
method and then onreadystatechange
set the callback function, the code will be override
again, you can override
not produce the desired effect.
How can you correctly override XHR? Put the code together and look at it:
;(function () {function Ajaxeventtrigger (event) {var ajaxevent = new Customevent (event, {detail:this});
Window.dispatchevent (ajaxevent); var oldxhr = window.
XMLHttpRequest;
function newxhr () {var realxhr = new Oldxhr ();
Realxhr.addeventlistener (' Abort ', function () {Ajaxeventtrigger.call (this, ' ajaxabort ');}, False);
Realxhr.addeventlistener (' Error ', function () {Ajaxeventtrigger.call (this, ' ajaxerror ');}, False);
Realxhr.addeventlistener (' Load ', function () {Ajaxeventtrigger.call (this, ' ajaxload ');}, False);
Realxhr.addeventlistener (' Loadstart ', function () {Ajaxeventtrigger.call (this, ' Ajaxloadstart ');}, False);
Realxhr.addeventlistener (' Progress ', function () {Ajaxeventtrigger.call (this, ' ajaxprogress ');}, False);
Realxhr.addeventlistener (' timeout ', function () {Ajaxeventtrigger.call (this, ' ajaxtimeout ');}, False);
Realxhr.addeventlistener (' Loadend ', function () {Ajaxeventtrigger.call (this, ' ajaxloadend ');}, False); Realxhr.addeventlistener (' ReadyStateChange ', function () {Ajaxeventtrigger.call (this, ' ajaxreadystatechange ');
FALSE);
return REALXHR; } window.
XMLHttpRequest = NEWXHR; })();
This allows you to XHR
add a custom event. How do I call it?
var xhr = new XMLHttpRequest ();
Window.addeventlistener (' Ajaxreadystatechange ', function (e) {
console.log (e.detail);//XMLHttpRequest Object
});
Window.addeventlistener (' Ajaxabort ', function (e) {
console.log (e.detail.responsetext);//XHR return content
});
Xhr.open (' Get ', ' Info.json ');
Xhr.send ();
It should be noted that normal readystatechange
and other events handler
return the e
XMLHttpRequest
object, but the custom method ajaxReadyStateChange
and other events handler return the e
CustomEvent
object, but e.detail
the real XMLHttpRequest
object. Getting Ajax requests to return content e.responseText
also needs to be modified to e.detail.responseText
.
Also, the addEventListener
method must be mounted window 对象
on, not on the XHR
instance.
Because the above code uses the Customevent
constructor, which is normally available on modern browsers, but is not supported by IE, even IE 11, you need to add polyfill
, which is the case:
;(function () {if (typeof window).
Customevent = = "function") return false; function Customevent (event, params) {params = params | |
{bubbles:false, cancelable:false, detail:undefined};
var evt = document.createevent (' customevent ');
Evt.initcustomevent (event, Params.bubbles, Params.cancelable, Params.detail);
return evt; } customevent.prototype = window.
Event.prototype; Window.
Customevent = customevent;
})();
;(function () {function Ajaxeventtrigger (event) {var ajaxevent = new Customevent (event, {detail:this});
Window.dispatchevent (ajaxevent); var oldxhr = window.
XMLHttpRequest;
function newxhr () {var realxhr = new Oldxhr ();
Realxhr.addeventlistener (' Abort ', function () {Ajaxeventtrigger.call (this, ' ajaxabort ');}, False);
Realxhr.addeventlistener (' Error ', function () {Ajaxeventtrigger.call (this, ' ajaxerror ');}, False); Realxhr.addeventlistener (' Load ', function () {Ajaxeventtrigger.call (this, ' ajaxload ');}, False);
Realxhr.addeventlistener (' Loadstart ', function () {Ajaxeventtrigger.call (this, ' Ajaxloadstart ');}, False);
Realxhr.addeventlistener (' Progress ', function () {Ajaxeventtrigger.call (this, ' ajaxprogress ');}, False);
Realxhr.addeventlistener (' timeout ', function () {Ajaxeventtrigger.call (this, ' ajaxtimeout ');}, False);
Realxhr.addeventlistener (' Loadend ', function () {Ajaxeventtrigger.call (this, ' ajaxloadend ');}, False); Realxhr.addeventlistener (' ReadyStateChange ', function () {Ajaxeventtrigger.call (this, ' ajaxreadystatechange ');
FALSE);
return REALXHR; } window.
XMLHttpRequest = NEWXHR; })();
At this point, you can in IE 9+, Chrome 15+, FireFox 11+, Edge, Safari 6.1+, Opera 12.1+ happy to use, the above is the entire content of this article, I hope you can enjoy.