Reworked script and xhr abort logic to take advantage of the fact jXHR.abort will complete the request itself if not done already.
This commit is contained in:
parent
b07d43c649
commit
667a3b31e6
|
@ -47,7 +47,7 @@ jQuery.ajax.transport("script", function(s) {
|
||||||
script.src = s.url;
|
script.src = s.url;
|
||||||
|
|
||||||
// Attach handlers for all browsers
|
// Attach handlers for all browsers
|
||||||
script.onload = script.onreadystatechange = function( _ , statusText) {
|
script.onload = script.onreadystatechange = function( _ , isAbort ) {
|
||||||
|
|
||||||
if ( ! script.readyState || /loaded|complete/.test( script.readyState ) ) {
|
if ( ! script.readyState || /loaded|complete/.test( script.readyState ) ) {
|
||||||
|
|
||||||
|
@ -59,10 +59,13 @@ jQuery.ajax.transport("script", function(s) {
|
||||||
head.removeChild( script );
|
head.removeChild( script );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dereference the script
|
||||||
script = 0;
|
script = 0;
|
||||||
|
|
||||||
// Callback
|
// Callback if not abort
|
||||||
callback( statusText ? 0 : 200, statusText || "success" );
|
if ( ! isAbort ) {
|
||||||
|
callback( 200, "success" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// Use insertBefore instead of appendChild to circumvent an IE6 bug.
|
// Use insertBefore instead of appendChild to circumvent an IE6 bug.
|
||||||
|
@ -70,9 +73,9 @@ jQuery.ajax.transport("script", function(s) {
|
||||||
head.insertBefore( script, head.firstChild );
|
head.insertBefore( script, head.firstChild );
|
||||||
},
|
},
|
||||||
|
|
||||||
abort: function(statusText) {
|
abort: function() {
|
||||||
if ( script ) {
|
if ( script ) {
|
||||||
script.onload( 0 , statusText );
|
script.onload(0,1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,8 +9,8 @@ var // Next fake timer id
|
||||||
// XHR pool
|
// XHR pool
|
||||||
xhrPool = [],
|
xhrPool = [],
|
||||||
|
|
||||||
// #5280: see end of file
|
// #5280: see below
|
||||||
xhrUnloadAbortMarker;
|
xhrUnloadAbortInstalled;
|
||||||
|
|
||||||
|
|
||||||
jQuery.ajax.transport( function( s , determineDataType ) {
|
jQuery.ajax.transport( function( s , determineDataType ) {
|
||||||
|
@ -25,25 +25,23 @@ jQuery.ajax.transport( function( s , determineDataType ) {
|
||||||
send: function(headers, complete) {
|
send: function(headers, complete) {
|
||||||
|
|
||||||
// #5280: we need to abort on unload or IE will keep connections alive
|
// #5280: we need to abort on unload or IE will keep connections alive
|
||||||
if ( ! xhrUnloadAbortMarker ) {
|
if ( ! xhrUnloadAbortInstalled ) {
|
||||||
|
|
||||||
xhrUnloadAbortMarker = [];
|
xhrUnloadAbortInstalled = 1;
|
||||||
|
|
||||||
jQuery(window).bind( "unload" , function() {
|
jQuery(window).bind( "unload" , function() {
|
||||||
|
|
||||||
// Abort all pending requests
|
// Abort all pending requests
|
||||||
jQuery.each(xhrs, function(_, xhr) {
|
jQuery.each(xhrs, function(_, xhr) {
|
||||||
if ( xhr.onreadystatechange ) {
|
if ( xhr.onreadystatechange ) {
|
||||||
xhr.onreadystatechange( xhrUnloadAbortMarker );
|
xhr.onreadystatechange( 1 );
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Reset polling structure to be safe
|
|
||||||
xhrs = {};
|
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get a new xhr
|
||||||
var xhr = xhrPool.pop() || s.xhr(),
|
var xhr = xhrPool.pop() || s.xhr(),
|
||||||
handle;
|
handle;
|
||||||
|
|
||||||
|
@ -58,7 +56,7 @@ jQuery.ajax.transport( function( s , determineDataType ) {
|
||||||
// Requested-With header
|
// Requested-With header
|
||||||
// Not set for crossDomain requests with no content
|
// Not set for crossDomain requests with no content
|
||||||
// (see why at http://trac.dojotoolkit.org/ticket/9486)
|
// (see why at http://trac.dojotoolkit.org/ticket/9486)
|
||||||
// Won't change header if already provided in beforeSend
|
// Won't change header if already provided
|
||||||
if ( ! ( s.crossDomain && ! s.hasContent ) && ! headers["x-requested-with"] ) {
|
if ( ! ( s.crossDomain && ! s.hasContent ) && ! headers["x-requested-with"] ) {
|
||||||
headers["x-requested-with"] = "XMLHttpRequest";
|
headers["x-requested-with"] = "XMLHttpRequest";
|
||||||
}
|
}
|
||||||
|
@ -76,20 +74,23 @@ jQuery.ajax.transport( function( s , determineDataType ) {
|
||||||
try {
|
try {
|
||||||
xhr.send( ( s.hasContent && s.data ) || null );
|
xhr.send( ( s.hasContent && s.data ) || null );
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
// Store back in pool
|
// Store back into pool
|
||||||
xhrPool.push( xhr );
|
xhrPool.push( xhr );
|
||||||
complete(0, "error", "" + e);
|
complete(0, "error", "" + e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listener
|
// Listener
|
||||||
callback = function ( abortStatusText ) {
|
callback = function( isAbort ) {
|
||||||
|
|
||||||
// Was never called and is aborted or complete
|
// Was never called and is aborted or complete
|
||||||
if ( callback && ( abortStatusText || xhr.readyState === 4 ) ) {
|
if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
|
||||||
|
|
||||||
// Do not listen anymore
|
// Only called once
|
||||||
// and Store back in pool
|
callback = 0;
|
||||||
|
|
||||||
|
// Do not keep as active anymore
|
||||||
|
// and store back into pool
|
||||||
if (handle) {
|
if (handle) {
|
||||||
xhr.onreadystatechange = jQuery.noop;
|
xhr.onreadystatechange = jQuery.noop;
|
||||||
delete xhrs[ handle ];
|
delete xhrs[ handle ];
|
||||||
|
@ -97,28 +98,20 @@ jQuery.ajax.transport( function( s , determineDataType ) {
|
||||||
xhrPool.push( xhr );
|
xhrPool.push( xhr );
|
||||||
}
|
}
|
||||||
|
|
||||||
callback = 0;
|
// If it's an abort
|
||||||
|
if ( isAbort ) {
|
||||||
// Get info
|
|
||||||
var status, statusText, response, responseHeaders;
|
|
||||||
|
|
||||||
if ( abortStatusText ) {
|
|
||||||
|
|
||||||
|
// Abort it manually if needed
|
||||||
if ( xhr.readyState !== 4 ) {
|
if ( xhr.readyState !== 4 ) {
|
||||||
xhr.abort();
|
xhr.abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop here if unloadAbort
|
|
||||||
if ( abortStatusText === xhrUnloadAbortMarker ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = 0;
|
|
||||||
statusText = abortStatusText;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
status = xhr.status;
|
// Get info
|
||||||
|
var status = xhr.status,
|
||||||
|
statusText,
|
||||||
|
response,
|
||||||
|
responseHeaders = xhr.getAllResponseHeaders();
|
||||||
|
|
||||||
try { // Firefox throws an exception when accessing statusText for faulty cross-domain requests
|
try { // Firefox throws an exception when accessing statusText for faulty cross-domain requests
|
||||||
|
|
||||||
|
@ -130,8 +123,6 @@ jQuery.ajax.transport( function( s , determineDataType ) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
responseHeaders = xhr.getAllResponseHeaders();
|
|
||||||
|
|
||||||
// Filter status for non standard behaviours
|
// Filter status for non standard behaviours
|
||||||
// (so many they seem to be the actual "standard")
|
// (so many they seem to be the actual "standard")
|
||||||
status =
|
status =
|
||||||
|
@ -164,10 +155,10 @@ jQuery.ajax.transport( function( s , determineDataType ) {
|
||||||
xhr.getResponseHeader("content-type"),
|
xhr.getResponseHeader("content-type"),
|
||||||
xhr.responseText,
|
xhr.responseText,
|
||||||
xhr.responseXML );
|
xhr.responseXML );
|
||||||
}
|
|
||||||
|
|
||||||
// Call complete
|
// Call complete
|
||||||
complete(status,statusText,response,responseHeaders);
|
complete(status,statusText,response,responseHeaders);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -189,9 +180,9 @@ jQuery.ajax.transport( function( s , determineDataType ) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
abort: function(statusText) {
|
abort: function() {
|
||||||
if ( callback ) {
|
if ( callback ) {
|
||||||
callback(statusText);
|
callback(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue