Fix memory leaks in IE caused by the custom abort function of $.ajax. Fixes bug ...
[jquery.git] / src / ajax.js
index ff293da..6ea61eb 100644 (file)
@@ -195,6 +195,17 @@ jQuery.extend({
        },
 
        ajax: function( origSettings ) {
+               // IE8 leaks a lot when we've set abort, and IE6-8 a little
+               // when we have set onreadystatechange. Bug #6242
+               // XXX IE7 still leaks when abort is called, no matter what
+               // we do
+               function cleanup() {
+                       // IE6 will throw an error setting xhr.abort
+                       try {
+                               xhr.abort = xhr.onreadystatechange = jQuery.noop;
+                       } catch(e) {}
+               }
+
                var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings),
                        jsonp, status, data, type = s.type.toUpperCase(), noContent = rnoContent.test(type);
 
@@ -403,13 +414,12 @@ jQuery.extend({
 
                                requestDone = true;
                                if ( xhr ) {
-                                       xhr.onreadystatechange = jQuery.noop;
+                                       cleanup();
                                }
 
                        // The transfer is complete and the data is available, or the request timed out
                        } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
                                requestDone = true;
-                               xhr.onreadystatechange = jQuery.noop;
 
                                status = isTimeout === "timeout" ?
                                        "timeout" :
@@ -451,10 +461,7 @@ jQuery.extend({
                                        xhr.abort();
                                }
 
-                               // Stop memory leaks
-                               if ( s.async ) {
-                                       xhr = null;
-                               }
+                               cleanup();
                        }
                };
 
@@ -463,10 +470,11 @@ jQuery.extend({
                try {
                        var oldAbort = xhr.abort;
                        xhr.abort = function() {
-                               // xhr.abort in IE7 is not a native JS function
-                               // and does not have a call property
-                               if ( xhr && oldAbort.call ) {
-                                       oldAbort.call( xhr );
+                               if ( xhr ) {
+                                       // oldAbort has no call property in IE7 so
+                                       // just do it this way, which works in all
+                                       // browsers
+                                       Function.prototype.call.call( oldAbort, xhr );
                                }
 
                                onreadystatechange( "abort" );
@@ -506,11 +514,12 @@ jQuery.extend({
        // Serialize an array of form elements or a set of
        // key/values into a query string
        param: function( a, traditional ) {
-               var s = [], add = function( key, value ) {
-                       // If value is a function, invoke it and return its value
-                       value = jQuery.isFunction(value) ? value() : value;
-                       s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
-               };
+               var s = [],
+                       add = function( key, value ) {
+                               // If value is a function, invoke it and return its value
+                               value = jQuery.isFunction(value) ? value() : value;
+                               s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
+                       };
                
                // Set traditional to true for jQuery <= 1.3.2 behavior.
                if ( traditional === undefined ) {