Share the JavaScript method for listening to all Ajax request events, javascriptajax
If the Ajax request is made by jQuery$.ajax
By default, you can use jQuery's Global Ajax Event Handlers to listen to Ajax events. However, I encountered an Ajax request initiated using native JavaScript, so this method won't work.
There are other methods, such as Pub/Sub, but I cannot modify the js Code that initiates the request, so there is no problem of adding publish to the code. Similarly, jQuery's.bind
And.trigger
And cannot be used.
Finally, we decided to useoverride XMLHttpRequest
And use custom events together.
Search on StackOverflow and find that some nuts provide an unreliable solution. Well, I will post it for you to see:
;(function () { var open = window.XMLHttpRequest.prototype.open, send = window.XMLHttpRequest.prototype.send, onReadyStateChange; function openReplacement(method, url, async, user, password) { // some code return open.apply(this, arguments); } function sendReplacement(data) { // some code if(this.onreadystatechange) this._onreadystatechange = this.onreadystatechange; this.onreadystatechange = onReadyStateChangeReplacement; return send.apply(this, arguments); } function onReadyStateChangeReplacement() { // some code if (this._onreadystatechange) return this._onreadystatechange.apply(this, arguments); } window.XMLHttpRequest.prototype.open = openReplacement; window.XMLHttpRequest.prototype.send = sendReplacement;})();
This solution cannot listen to allXHR Events
Andreadystatechange
The event is calledsend
Method.readyState = 1
Event. At the same time, if you are usingsend
Method and thenonreadystatechange
Set the callback functionoverride
Code againoverride
And cannot produce the expected results.
So how can we override XHR correctly? Paste the code and take a look:
;(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;})();
In this wayXHR
Added custom events. How to call it?
Var xhr = new XMLHttpRequest (); window. addEventListener ('ajaxreadystatechang', function (e) {console. log (e. detail); // XMLHttpRequest Object}); window. addEventListener ('ajaxabort ', function (e) {console. log (e. detail. responseText); // The content returned by XHR}); xhr. open ('get', 'info. json '); xhr. send ();
Note that it is normalreadystatechange
And other eventshandler
Returnede
YesXMLHttpRequest
Object, but the custom MethodajaxReadyStateChange
And other events returned by handler.e
YesCustomEvent
Object, ande.detail
Is trueXMLHttpRequest
Object. Thee.responseText
You also need to changee.detail.responseText
.
At the same time,addEventListener
Method must be mounted onWindow object
But notXHR
Instance.
Because the above code is usedCustomEvent
Constructor can be used normally in modern browsers, but it is not supported in IE or even in IE 11.Polyfill
, It becomes like this:
;(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;})();
Now, you can enjoy using IE 9 +, Chrome 15 +, FireFox 11 +, Edge, Safari 6.1 +, and Opera 12.1 +. The above is all the content of this article, I hope you will like it.