diff options
-rw-r--r-- | src/ajax/xhr.js | 23 | ||||
-rw-r--r-- | test/data/ajax/unreleasedXHR.html | 25 | ||||
-rw-r--r-- | test/unit/ajax.js | 5 |
3 files changed, 49 insertions, 4 deletions
diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js index 72703a0b1..3a9c9e968 100644 --- a/src/ajax/xhr.js +++ b/src/ajax/xhr.js @@ -11,8 +11,22 @@ var xhrSupported = jQuery.ajaxSettings.xhr(), // Support: IE9 // #1450: sometimes IE returns 1223 when it should be 204 1223: 204 - }; - + }, + // Support: IE9 + // We need to keep track of outbound xhr and abort them manually + // because IE is not smart enough to do it all by itself + xhrId = 0, + xhrCallbacks = {}; + +if ( window.ActiveXObject ) { + jQuery( window ).on( "unload", function() { + for( var key in xhrCallbacks ) { + xhrCallbacks[ key ](); + } + xhrCallbacks = undefined; + }); +} + jQuery.support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); jQuery.support.ajax = xhrSupported = !!xhrSupported; @@ -22,7 +36,7 @@ jQuery.ajaxTransport(function( options ) { if ( jQuery.support.cors || xhrSupported && !options.crossDomain ) { return { send: function( headers, complete ) { - var i, + var i, id, xhr = options.xhr(); xhr.open( options.type, options.url, options.async, options.username, options.password ); // Apply custom fields if provided @@ -51,6 +65,7 @@ jQuery.ajaxTransport(function( options ) { callback = function( type ) { return function() { if ( callback ) { + delete xhrCallbacks[ id ]; callback = xhr.onload = xhr.onerror = null; if ( type === "abort" ) { xhr.abort(); @@ -80,7 +95,7 @@ jQuery.ajaxTransport(function( options ) { xhr.onload = callback(); xhr.onerror = callback("error"); // Create the abort callback - callback = callback("abort"); + callback = xhrCallbacks[( id = xhrId++ )] = callback("abort"); // Do send the request // This may raise an exception which is actually // handled in jQuery.ajax (so no try/catch here) diff --git a/test/data/ajax/unreleasedXHR.html b/test/data/ajax/unreleasedXHR.html new file mode 100644 index 000000000..d516a0c52 --- /dev/null +++ b/test/data/ajax/unreleasedXHR.html @@ -0,0 +1,25 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> +<head> +<meta http-equiv="content-type" content="text/html; charset=utf-8"> +<title>Attempt to block tests because of dangling XHR requests (IE)</title> +<script type="text/javascript" src="../../../dist/jquery.js"></script> +<script type="text/javascript"> +window.onunload = function() {}; +jQuery(function() { + setTimeout(function() { + var parent = window.parent; + document.write(""); + parent.iframeCallback(); + }, 200 ); + var number = 50; + while( number-- ) { + jQuery.ajax("../name.php?wait=600"); + } +}); +</script> +</head> +<body> +<!-- empty body --> +</body> +</html> diff --git a/test/unit/ajax.js b/test/unit/ajax.js index e3180c5a3..25d942e37 100644 --- a/test/unit/ajax.js +++ b/test/unit/ajax.js @@ -30,6 +30,11 @@ module( "ajax", { //----------- jQuery.ajax() + testIframeWithCallback( "XMLHttpRequest - Attempt to block tests because of dangling XHR requests (IE)", "ajax/unreleasedXHR.html", function() { + expect( 1 ); + ok( true, "done" ); + }); + ajaxTest( "jQuery.ajax() - success callbacks", 8, { setup: addGlobalEvents("ajaxStart ajaxStop ajaxSend ajaxComplete ajaxSuccess"), url: url("data/name.html"), |