aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/ajax/jsonp.js14
-rw-r--r--test/unit/ajax.js45
2 files changed, 55 insertions, 4 deletions
diff --git a/src/ajax/jsonp.js b/src/ajax/jsonp.js
index e1f2b5314..9965b2230 100644
--- a/src/ajax/jsonp.js
+++ b/src/ajax/jsonp.js
@@ -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 ] );
diff --git a/test/unit/ajax.js b/test/unit/ajax.js
index d13eaaeca..cca72aa5c 100644
--- a/test/unit/ajax.js
+++ b/test/unit/ajax.js
@@ -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();
@@ -1331,6 +1331,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",
crossDomain: crossDomain,
@@ -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 );
+
});
});