X-Git-Url: http://git.asbjorn.it/?a=blobdiff_plain;f=src%2Fajax%2Fjsonp.js;h=f5742d998bd6bb6069c28a815214abaa255b27bc;hb=ee22c8b34bb801f26cacc67a1a3a0ac595fe7928;hp=5cfb7834af507a37e29f5ecf98617499ebb7e888;hpb=c43b078c6911027fd4124d542446ad0098662f6a;p=jquery.git diff --git a/src/ajax/jsonp.js b/src/ajax/jsonp.js index 5cfb783..f5742d9 100644 --- a/src/ajax/jsonp.js +++ b/src/ajax/jsonp.js @@ -1,70 +1,70 @@ (function( jQuery ) { var jsc = jQuery.now(), - jsre = /\=\?(&|$)/, - rquery_jsonp = /\?/; + jsre = /(\=)(?:\?|%3F)(&|$)|()(?:\?\?|%3F%3F)()/i; -// Default jsonp callback name -jQuery.ajaxSettings.jsonpCallback = function() { - return "jsonp" + jsc++; -}; - -// Normalize jsonp queries -// 1) put callback parameter in url or data -// 2) sneakily ensure transportDataType is json -// 3) ensure options jsonp is always provided so that jsonp requests are always -// json request with the jsonp option set -jQuery.ajax.prefilter("json jsonp", function(s) { +// Default jsonp settings +jQuery.ajaxSetup({ + jsonp: "callback", + jsonpCallback: function() { + return "jsonp" + jsc++; + } +}); - var transportDataType = s.dataTypes[ 0 ]; +// Detect, normalize options and install callbacks for jsonp requests +jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, dataIsString /* internal */ ) { - s.dataTypes[ 0 ] = "json"; + dataIsString = ( typeof s.data === "string" ); - if ( s.jsonp || - transportDataType === "jsonp" || - transportDataType === "json" && ( jsre.test(s.url) || typeof(s.data) === "string" && jsre.test(s.data) ) ) { + if ( s.dataTypes[ 0 ] === "jsonp" || + originalSettings.jsonpCallback || + originalSettings.jsonp != null || + s.jsonp !== false && ( jsre.test( s.url ) || + dataIsString && jsre.test( s.data ) ) ) { - var jsonp = s.jsonp = s.jsonp || "callback", + var responseContainer, jsonpCallback = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback, - url = s.url.replace(jsre, "=" + jsonpCallback + "$1"), - data = s.url == url && typeof(s.data) === "string" ? s.data.replace(jsre, "=" + jsonpCallback + "$1") : s.data; - - if ( url == s.url && data == s.data ) { - url = url += (rquery_jsonp.test( url ) ? "&" : "?") + jsonp + "=" + jsonpCallback; + previous = window[ jsonpCallback ], + url = s.url, + data = s.data, + replace = "$1" + jsonpCallback + "$2"; + + if ( s.jsonp !== false ) { + url = url.replace( jsre, replace ); + if ( s.url === url ) { + if ( dataIsString ) { + data = data.replace( jsre, replace ); + } + if ( s.data === data ) { + // Add callback manually + url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback; + } + } } s.url = url; s.data = data; - } - -// Bind transport to json dataType -}).transport("json", function(s) { - if ( s.jsonp ) { - - // Put callback in place - var responseContainer, - jsonpCallback = s.jsonpCallback, - previous = window[ jsonpCallback ]; - - window [ jsonpCallback ] = function( response ) { - responseContainer = [response]; + window[ jsonpCallback ] = function( response ) { + responseContainer = [ response ]; }; - s.complete = [function() { + s.complete = [ function() { // Set callback back to previous value window[ jsonpCallback ] = previous; // Call if it was a function and we have a response if ( previous) { - if ( responseContainer && jQuery.isFunction ( previous ) ) { - window[ jsonpCallback ] ( responseContainer[0] ); + if ( responseContainer && jQuery.isFunction( previous ) ) { + window[ jsonpCallback ] ( responseContainer[ 0 ] ); } } else { // else, more memory leak avoidance - try{ delete window[ jsonpCallback ]; } catch(e){} + try{ + delete window[ jsonpCallback ]; + } catch( e ) {} } }, s.complete ]; @@ -77,9 +77,12 @@ jQuery.ajax.prefilter("json jsonp", function(s) { return responseContainer[ 0 ]; }; - // Delegate to script transport + // force json dataType + s.dataTypes[ 0 ] = "json"; + + // Delegate to script return "script"; } -}); +} ); })( jQuery );