@@ -25,7 +25,7 @@ support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
25
25
support . ajax = xhrSupported = ! ! xhrSupported ;
26
26
27
27
jQuery . ajaxTransport ( function ( options ) {
28
- var callback ;
28
+ var callback , errorCallback ;
29
29
30
30
// Cross domain only allowed if supported through XMLHttpRequest
31
31
if ( support . cors || xhrSupported && ! options . crossDomain ) {
@@ -72,17 +72,26 @@ jQuery.ajaxTransport( function( options ) {
72
72
callback = function ( type ) {
73
73
return function ( ) {
74
74
if ( callback ) {
75
- callback = xhr . onload = xhr . onerror = null ;
75
+ callback = errorCallback = xhr . onload =
76
+ xhr . onerror = xhr . onabort = xhr . onreadystatechange = null ;
76
77
77
78
if ( type === "abort" ) {
78
79
xhr . abort ( ) ;
79
80
} else if ( type === "error" ) {
80
- complete (
81
81
82
- // File: protocol always yields status 0; see #8605, #14207
83
- xhr . status ,
84
- xhr . statusText
85
- ) ;
82
+ // Support: IE9
83
+ // On a manual native abort, IE9 throws
84
+ // errors on any property access that is not readyState
85
+ if ( typeof xhr . status !== "number" ) {
86
+ complete ( 0 , "error" ) ;
87
+ } else {
88
+ complete (
89
+
90
+ // File: protocol always yields status 0; see #8605, #14207
91
+ xhr . status ,
92
+ xhr . statusText
93
+ ) ;
94
+ }
86
95
} else {
87
96
complete (
88
97
xhrSuccessStatus [ xhr . status ] || xhr . status ,
@@ -103,7 +112,31 @@ jQuery.ajaxTransport( function( options ) {
103
112
104
113
// Listen to events
105
114
xhr . onload = callback ( ) ;
106
- xhr . onerror = callback ( "error" ) ;
115
+ errorCallback = xhr . onerror = callback ( "error" ) ;
116
+
117
+ // Support: IE9
118
+ // Use onreadystatechange to replace onabort
119
+ // to handle uncaught aborts
120
+ if ( xhr . onabort !== undefined ) {
121
+ xhr . onabort = errorCallback ;
122
+ } else {
123
+ xhr . onreadystatechange = function ( ) {
124
+
125
+ // Check readyState before timeout as it changes
126
+ if ( xhr . readyState === 4 ) {
127
+
128
+ // Allow onerror to be called first,
129
+ // but that will not handle a native abort
130
+ // Also, save errorCallback to a variable
131
+ // as xhr.onerror cannot be accessed
132
+ window . setTimeout ( function ( ) {
133
+ if ( callback ) {
134
+ errorCallback ( ) ;
135
+ }
136
+ } ) ;
137
+ }
138
+ } ;
139
+ }
107
140
108
141
// Create the abort callback
109
142
callback = callback ( "abort" ) ;
0 commit comments