How JavaScript listens to all Ajax request events

Source: Internet
Author: User


Recently, a blogger is working on a small project and introduced a third-party js file. This file will call XMLHttpRequest to send Ajax requests to the server, but I have some events that need to listen to their Ajax requests, to execute other scripts. So I looked at the event method for listening to Ajax requests and shared it with you here.

 
If the Ajax request is composed of $. ajax is initiated. By default, jQuery's Global Ajax Event Handlers can be used to listen to Ajax events. However, I encountered Ajax requests initiated by native JavaScript, so this method won't work.

Then, there are other methods, such as Pub/Sub, that is, ps: // github.com/cowboy/jquery-tiny-pubsub "> https://github.com/cowboy/jquery-tiny-pubsub jQuery plug-in, but the js code that initiates the request can not be modified, there is no problem of adding publish to the code. Similarly, jQuery's. bind and. trigger cannot be used either.

Finally, we decided to use the direct override XMLHttpRequest and use the custom event together.


 
Search on StackOverflow and find that some nuts provide an unreliable solution. Well, I will post it for you to see:

Show source
In this solution, you cannot listen to all XHR Events, and the readystatechange event is only listened to after the send method is called, so you cannot listen to Events with readyState = 1. At the same time, if you set a callback function for onreadystatechange after using the send method, the override code will be override again, which will not produce the expected results.
 

So how can we override XHR correctly? Paste the code to save your life:

; (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 ('readystatechang', function () {ajaxEventTrigger. call (this, 'ajaxreadystatechang');}, false );
 
Return realXHR;
    }
 
Window. XMLHttpRequest = newXHR;
})();

In this way, a custom event is added for XHR. 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); // content returned by XHR
});
 
Xhr. open ('GET', 'info. Json ');
Xhr. send ();

It should be noted that the normal event handler, such as readystatechange, returns e as the XMLHttpRequest object, but the custom method ajaxReadyStateChange and other event handler returns e as the CustomEvent object, while e. detail is the real XMLHttpRequest object. The e. responseText that obtains the content returned by the Ajax request also needs to be modified to e. detail. responseText.

At the same time, the addEventListener method must be mounted on the window object instead of the XHR instance.

 
Because the above code uses the CustomEvent constructor, it can be used normally in modern browsers, but in IE, it is not even supported by IE 11. Therefore, Polyfill needs to be added to the code as follows:

; (Function (){
If (typeof window. CustomEvent = "function") return false;
 
Function CustomEvent (event, params ){
Params = params | {bubbles: false, cancelable: false, detail: undefined };
Var evt = document. createEvent ('customent ');
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 ('readystatechang', function () {ajaxEventTrigger. call (this, 'ajaxreadystatechang');}, false );
 
Return realXHR;
    }
 
Window. XMLHttpRequest = newXHR;
})();
 
In this case, you can enjoy using caniuse on IE 9 +, Chrome 15 +, FireFox 11 +, Edge, Safari 6.1 +, and Opera 12.1 +.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.