diff options
author | Michał Gołębiowski-Owczarek <m.goleb@gmail.com> | 2020-07-27 19:15:57 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-27 19:15:57 +0200 |
commit | e7b3bc488d01d584262e12a7c5c25f935d0d034b (patch) | |
tree | 1e4f60870089f82a7dae69598a4121d4d778d8ea /src/ajax/jsonp.js | |
parent | fa0058af426c4e482059214c29c29f004254d9a1 (diff) | |
download | jquery-e7b3bc488d01d584262e12a7c5c25f935d0d034b.tar.gz jquery-e7b3bc488d01d584262e12a7c5c25f935d0d034b.zip |
Ajax: Drop the json to jsonp auto-promotion logic
Previously, `jQuery.ajax` with `dataType: 'json'` with a provided callback was
automatically converted to a jsonp request unless one also specified
`jsonp: false`. Today the preferred way of interacting with a cross-domain
backend is CORS which works in all browsers jQuery 4 will support.
Auto-promoting JSON requests to JSONP ones introduces a security issue as the
developer may be unaware they're not just downloading data but executing code
from a remote domain.
This commit disables the auto-promoting logic.
BREAKING CHANGE: to trigger a JSONP request, it's now required to specify
`dataType: "jsonp"`; previously some requests with `dataType: "json"` were
auto-promoted to JSONP.
Fixes gh-1799
Fixes gh-3376
Closes gh-4754
Diffstat (limited to 'src/ajax/jsonp.js')
-rw-r--r-- | src/ajax/jsonp.js | 100 |
1 files changed, 48 insertions, 52 deletions
diff --git a/src/ajax/jsonp.js b/src/ajax/jsonp.js index 1d612c1a9..e115fdafc 100644 --- a/src/ajax/jsonp.js +++ b/src/ajax/jsonp.js @@ -18,7 +18,7 @@ jQuery.ajaxSetup( { } ); // Detect, normalize options and install callbacks for jsonp requests -jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { +jQuery.ajaxPrefilter( "jsonp", function( s, originalSettings, jqXHR ) { var callbackName, overwritten, responseContainer, jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? @@ -29,69 +29,65 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { rjsonp.test( s.data ) && "data" ); - // Handle iff the expected data type is "jsonp" or we have a parameter to set - if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { + // Get callback name, remembering preexisting value associated with it + callbackName = s.jsonpCallback = typeof s.jsonpCallback === "function" ? + s.jsonpCallback() : + s.jsonpCallback; - // Get callback name, remembering preexisting value associated with it - callbackName = s.jsonpCallback = typeof s.jsonpCallback === "function" ? - s.jsonpCallback() : - s.jsonpCallback; + // Insert callback into url or form data + if ( jsonProp ) { + s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); + } else if ( s.jsonp !== false ) { + s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; + } - // Insert callback into url or form data - if ( jsonProp ) { - s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); - } else if ( s.jsonp !== false ) { - s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; + // Use data converter to retrieve json after script execution + s.converters[ "script json" ] = function() { + if ( !responseContainer ) { + jQuery.error( callbackName + " was not called" ); } + return responseContainer[ 0 ]; + }; - // Use data converter to retrieve json after script execution - s.converters[ "script json" ] = function() { - if ( !responseContainer ) { - jQuery.error( callbackName + " was not called" ); - } - return responseContainer[ 0 ]; - }; - - // Force json dataType - s.dataTypes[ 0 ] = "json"; + // Force json dataType + s.dataTypes[ 0 ] = "json"; - // Install callback - overwritten = window[ callbackName ]; - window[ callbackName ] = function() { - responseContainer = arguments; - }; + // Install callback + overwritten = window[ callbackName ]; + window[ callbackName ] = function() { + responseContainer = arguments; + }; - // Clean-up function (fires after converters) - jqXHR.always( function() { + // Clean-up function (fires after converters) + jqXHR.always( function() { - // If previous value didn't exist - remove it - if ( overwritten === undefined ) { - jQuery( window ).removeProp( callbackName ); + // If previous value didn't exist - remove it + if ( overwritten === undefined ) { + jQuery( window ).removeProp( callbackName ); - // Otherwise restore preexisting value - } else { - window[ callbackName ] = overwritten; - } + // Otherwise restore preexisting value + } else { + window[ callbackName ] = overwritten; + } - // Save back as free - if ( s[ callbackName ] ) { + // Save back as free + if ( s[ callbackName ] ) { - // Make sure that re-using the options doesn't screw things around - s.jsonpCallback = originalSettings.jsonpCallback; + // Make sure that re-using the options doesn't screw things around + s.jsonpCallback = originalSettings.jsonpCallback; - // Save the callback name for future use - oldCallbacks.push( callbackName ); - } + // Save the callback name for future use + oldCallbacks.push( callbackName ); + } - // Call if it was a function and we have a response - if ( responseContainer && typeof overwritten === "function" ) { - overwritten( responseContainer[ 0 ] ); - } + // Call if it was a function and we have a response + if ( responseContainer && typeof overwritten === "function" ) { + overwritten( responseContainer[ 0 ] ); + } - responseContainer = overwritten = undefined; - } ); + responseContainer = overwritten = undefined; + } ); - // Delegate to script - return "script"; - } + // Delegate to script + return "script"; } ); |