aboutsummaryrefslogtreecommitdiffstats
path: root/src/ajax/jsonp.js
diff options
context:
space:
mode:
authorMichał Gołębiowski-Owczarek <m.goleb@gmail.com>2020-07-27 19:15:57 +0200
committerGitHub <noreply@github.com>2020-07-27 19:15:57 +0200
commite7b3bc488d01d584262e12a7c5c25f935d0d034b (patch)
tree1e4f60870089f82a7dae69598a4121d4d778d8ea /src/ajax/jsonp.js
parentfa0058af426c4e482059214c29c29f004254d9a1 (diff)
downloadjquery-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.js100
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";
} );