Share the JavaScript method for listening to all Ajax request events, javascriptajax
If the Ajax request is made by jQuery$.ajaxBy 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.bindAnd.triggerAnd cannot be used.
Finally, we decided to useoverride XMLHttpRequestAnd 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 EventsAndreadystatechange The event is calledsend Method.readyState = 1Event. At the same time, if you are usingsend Method and thenonreadystatechange Set the callback functionoverride Code againoverrideAnd 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 ReturnedeYesXMLHttpRequest Object, but the custom MethodajaxReadyStateChange And other events returned by handler.eYesCustomEvent 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 objectBut 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.