@@ -40,7 +40,20 @@ jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
4040 // For all other browsers, use the standard XMLHttpRequest object
4141 createStandardXHR ;
4242
43- var xhrSupported = jQuery . ajaxSettings . xhr ( ) ;
43+ var xhrId = 0 ,
44+ xhrCallbacks = { } ,
45+ xhrSupported = jQuery . ajaxSettings . xhr ( ) ;
46+
47+ // Support: IE<10
48+ // Open requests must be manually aborted on unload (#5280)
49+ // See https://support.microsoft.com/kb/2856746 for more info
50+ if ( window . attachEvent ) {
51+ window . attachEvent ( "onunload" , function ( ) {
52+ for ( var key in xhrCallbacks ) {
53+ xhrCallbacks [ key ] ( undefined , true ) ;
54+ }
55+ } ) ;
56+ }
4457
4558// Determine support properties
4659support . cors = ! ! xhrSupported && ( "withCredentials" in xhrSupported ) ;
@@ -59,7 +72,8 @@ if ( xhrSupported ) {
5972 return {
6073 send : function ( headers , complete ) {
6174 var i ,
62- xhr = options . xhr ( ) ;
75+ xhr = options . xhr ( ) ,
76+ id = ++ xhrId ;
6377
6478 // Open the socket
6579 xhr . open (
@@ -105,6 +119,11 @@ if ( xhrSupported ) {
105119 }
106120 }
107121
122+ // Do send the request
123+ // This may raise an exception which is actually
124+ // handled in jQuery.ajax (so no try/catch here)
125+ xhr . send ( ( options . hasContent && options . data ) || null ) ;
126+
108127 // Listener
109128 callback = function ( _ , isAbort ) {
110129 var status , statusText , responses ;
@@ -113,6 +132,7 @@ if ( xhrSupported ) {
113132 if ( callback && ( isAbort || xhr . readyState === 4 ) ) {
114133
115134 // Clean up
135+ delete xhrCallbacks [ id ] ;
116136 callback = undefined ;
117137 xhr . onreadystatechange = jQuery . noop ;
118138
@@ -168,8 +188,6 @@ if ( xhrSupported ) {
168188 // handled in jQuery.ajax (so no try/catch here)
169189 if ( ! options . async ) {
170190
171- xhr . send ( ( options . hasContent && options . data ) || null ) ;
172-
173191 // If we're in sync mode we fire the callback
174192 callback ( ) ;
175193 } else if ( xhr . readyState === 4 ) {
@@ -180,13 +198,8 @@ if ( xhrSupported ) {
180198 } else {
181199
182200 // Register the callback, but delay it in case `xhr.send` throws
183- xhr . onreadystatechange = function ( ) {
184- if ( callback ) {
185- window . setTimeout ( callback ) ;
186- }
187- } ;
188-
189- xhr . send ( ( options . hasContent && options . data ) || null ) ;
201+ // Add to the list of active xhr callbacks
202+ xhr . onreadystatechange = xhrCallbacks [ id ] = callback ;
190203 }
191204 } ,
192205
0 commit comments