]> source.dussan.org Git - jquery.git/commitdiff
Fixes #8205. Mitigates memory usage by recycling jsonp callback names the safest...
authorjaubourg <j@ubourg.net>
Fri, 20 Apr 2012 01:02:20 +0000 (03:02 +0200)
committerjaubourg <j@ubourg.net>
Fri, 20 Apr 2012 01:02:20 +0000 (03:02 +0200)
src/ajax/jsonp.js
test/unit/ajax.js

index e1f2b5314e81ed30ae09ed21c7566cbfb7dbf84a..9965b2230bc703a96c72533f1500cfeaa23173fa 100644 (file)
@@ -1,13 +1,16 @@
 (function( jQuery ) {
 
 var jsc = jQuery.now(),
-       jsre = /(\=)\?(&|$)|\?\?/i;
+       jsre = /(\=)\?(&|$)|\?\?/i,
+       jscallbacks = [];
 
 // Default jsonp settings
 jQuery.ajaxSetup({
        jsonp: "callback",
        jsonpCallback: function() {
-               return jQuery.expando + "_" + ( jsc++ );
+               var callback = jscallbacks.pop() || ( jQuery.expando + "_" + ( jsc++ ) );
+               this[ callback ] = true;
+               return callback;
        }
 });
 
@@ -53,6 +56,13 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
                jqXHR.always(function() {
                        // Set callback back to previous value
                        window[ jsonpCallback ] = previous;
+                       // Save back as free
+                       if ( s[ jsonpCallback ] ) {
+                               // make sure that re-using the options doesn't screw things around
+                               s.jsonpCallback = originalSettings.jsonpCallback;
+                               // save the callback name for future use
+                               jscallbacks.push( jsonpCallback );
+                       }
                        // Call if it was a function and we have a response
                        if ( responseContainer && jQuery.isFunction( previous ) ) {
                                window[ jsonpCallback ]( responseContainer[ 0 ] );
index d13eaaeca1e0dfad4b80f9f45c35e63184bef919..cca72aa5c3add5bab4df184fe83a4362187e6db8 100644 (file)
@@ -1309,10 +1309,10 @@ test("jQuery.getScript(String, Function) - no callback", function() {
 jQuery.each( [ "Same Domain", "Cross Domain" ] , function( crossDomain , label ) {
 
        test("jQuery.ajax() - JSONP, " + label, function() {
-               expect(20);
+               expect(24);
 
                var count = 0;
-               function plus(){ if ( ++count == 18 ) start(); }
+               function plus(){ if ( ++count == 20 ) start(); }
 
                stop();
 
@@ -1330,6 +1330,25 @@ jQuery.each( [ "Same Domain", "Cross Domain" ] , function( crossDomain , label )
                        }
                });
 
+               jQuery.ajax({
+                       url: "data/jsonp.php",
+                       dataType: "jsonp",
+                       crossDomain: crossDomain,
+                       success: function(data){
+                               ok( data.data, ( this.alreadyDone ? "this re-used" : "first request" ) + ": JSON results returned (GET, no callback)" );
+                               if ( !this.alreadyDone ) {
+                                       this.alreadyDone = true;
+                                       jQuery.ajax( this );
+                               } else {
+                                       plus();
+                               }
+                       },
+                       error: function(data){
+                               ok( false, "Ajax error JSON (GET, no callback)" );
+                               plus();
+                       }
+               });
+
                jQuery.ajax({
                        url: "data/jsonp.php?callback=?",
                        dataType: "jsonp",
@@ -1564,6 +1583,28 @@ jQuery.each( [ "Same Domain", "Cross Domain" ] , function( crossDomain , label )
                        }
                });
 
+               //#8205
+               jQuery.ajax({
+                       url: "data/jsonp.php",
+                       dataType: "jsonp",
+                       crossDomain: crossDomain,
+                       beforeSend: function() {
+                               this.callback = this.jsonpCallback;
+                       }
+               }).pipe(function() {
+                       var previous = this;
+                       strictEqual( previous.jsonpCallback, undefined, "jsonpCallback option is set back to default in callbacks" );
+                       jQuery.ajax({
+                               url: "data/jsonp.php",
+                               dataType: "jsonp",
+                               crossDomain: crossDomain,
+                               beforeSend: function() {
+                                       strictEqual( this.jsonpCallback, previous.callback, "JSONP callback name is re-used" );
+                                       return false;
+                               }
+                       });
+               }).always( plus );
+
        });
 });