mirror of
https://github.com/jquery/jquery.git
synced 2024-11-23 02:54:22 +00:00
Ajax: Support headers
for script transport even when cross-domain
The AJAX script transport has two versions: XHR + `jQuery.globalEval` or appending a script tag (note that `jQuery.globalEval` also appends a script tag now, but inline). The former cannot support the `headers` option which has so far not been taken into account. For jQuery 3.x, the main consequence was the option not being respected for cross-domain requests. Since in 4.x we use the latter way more often, the option was being ignored in more cases. The transport now checks whether the `headers` option is specified and uses the XHR way unless `scriptAttrs` are specified as well. Fixes gh-5142 Closes gh-5193
This commit is contained in:
parent
b02a257f98
commit
6d1364431b
@ -6,8 +6,14 @@ import "../ajax.js";
|
|||||||
function canUseScriptTag( s ) {
|
function canUseScriptTag( s ) {
|
||||||
|
|
||||||
// A script tag can only be used for async, cross domain or forced-by-attrs requests.
|
// A script tag can only be used for async, cross domain or forced-by-attrs requests.
|
||||||
|
// Requests with headers cannot use a script tag. However, when both `scriptAttrs` &
|
||||||
|
// `headers` options are specified, both are impossible to satisfy together; we
|
||||||
|
// prefer `scriptAttrs` then.
|
||||||
// Sync requests remain handled differently to preserve strict script ordering.
|
// Sync requests remain handled differently to preserve strict script ordering.
|
||||||
return s.crossDomain || s.scriptAttrs ||
|
return s.scriptAttrs || (
|
||||||
|
!s.headers &&
|
||||||
|
(
|
||||||
|
s.crossDomain ||
|
||||||
|
|
||||||
// When dealing with JSONP (`s.dataTypes` include "json" then)
|
// When dealing with JSONP (`s.dataTypes` include "json" then)
|
||||||
// don't use a script tag so that error responses still may have
|
// don't use a script tag so that error responses still may have
|
||||||
@ -16,10 +22,12 @@ function canUseScriptTag( s ) {
|
|||||||
// * have `scriptAttrs` set as that's a script-only functionality
|
// * have `scriptAttrs` set as that's a script-only functionality
|
||||||
// Note that this means JSONP requests violate strict CSP script-src settings.
|
// Note that this means JSONP requests violate strict CSP script-src settings.
|
||||||
// A proper solution is to migrate from using JSONP to a CORS setup.
|
// A proper solution is to migrate from using JSONP to a CORS setup.
|
||||||
( s.async && jQuery.inArray( "json", s.dataTypes ) < 0 );
|
( s.async && jQuery.inArray( "json", s.dataTypes ) < 0 )
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Install script dataType. Don't specify `content.script` so that an explicit
|
// Install script dataType. Don't specify `contents.script` so that an explicit
|
||||||
// `dataType: "script"` is required (see gh-2432, gh-4822)
|
// `dataType: "script"` is required (see gh-2432, gh-4822)
|
||||||
jQuery.ajaxSetup( {
|
jQuery.ajaxSetup( {
|
||||||
accepts: {
|
accepts: {
|
||||||
|
@ -71,11 +71,13 @@ QUnit.module( "ajax", {
|
|||||||
};
|
};
|
||||||
} );
|
} );
|
||||||
|
|
||||||
ajaxTest( "jQuery.ajax() - custom attributes for script tag", 5,
|
jQuery.each( [ " - Same Domain", " - Cross Domain" ], function( crossDomain, label ) {
|
||||||
|
ajaxTest( "jQuery.ajax() - custom attributes for script tag" + label, 5,
|
||||||
function( assert ) {
|
function( assert ) {
|
||||||
return {
|
return {
|
||||||
create: function( options ) {
|
create: function( options ) {
|
||||||
var xhr;
|
var xhr;
|
||||||
|
options.crossDomain = crossDomain;
|
||||||
options.method = "POST";
|
options.method = "POST";
|
||||||
options.dataType = "script";
|
options.dataType = "script";
|
||||||
options.scriptAttrs = { id: "jquery-ajax-test", async: "async" };
|
options.scriptAttrs = { id: "jquery-ajax-test", async: "async" };
|
||||||
@ -96,10 +98,64 @@ QUnit.module( "ajax", {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ajaxTest( "jQuery.ajax() - headers for script transport" + label, 3,
|
||||||
|
function( assert ) {
|
||||||
|
return {
|
||||||
|
create: function( options ) {
|
||||||
|
Globals.register( "corsCallback" );
|
||||||
|
window.corsCallback = function( response ) {
|
||||||
|
assert.strictEqual( response.headers[ "x-custom-test-header" ],
|
||||||
|
"test value", "Custom header sent" );
|
||||||
|
};
|
||||||
|
options.crossDomain = crossDomain;
|
||||||
|
options.dataType = "script";
|
||||||
|
options.headers = { "x-custom-test-header": "test value" };
|
||||||
|
return jQuery.ajax( url( "mock.php?action=script&callback=corsCallback" ), options );
|
||||||
|
},
|
||||||
|
success: function() {
|
||||||
|
assert.ok( true, "success" );
|
||||||
|
},
|
||||||
|
complete: function() {
|
||||||
|
assert.ok( true, "complete" );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
ajaxTest( "jQuery.ajax() - scriptAttrs winning over headers" + label, 4,
|
||||||
|
function( assert ) {
|
||||||
|
return {
|
||||||
|
create: function( options ) {
|
||||||
|
var xhr;
|
||||||
|
Globals.register( "corsCallback" );
|
||||||
|
window.corsCallback = function( response ) {
|
||||||
|
assert.ok( !response.headers[ "x-custom-test-header" ],
|
||||||
|
"headers losing with scriptAttrs" );
|
||||||
|
};
|
||||||
|
options.crossDomain = crossDomain;
|
||||||
|
options.dataType = "script";
|
||||||
|
options.scriptAttrs = { id: "jquery-ajax-test", async: "async" };
|
||||||
|
options.headers = { "x-custom-test-header": "test value" };
|
||||||
|
xhr = jQuery.ajax( url( "mock.php?action=script&callback=corsCallback" ), options );
|
||||||
|
assert.equal( jQuery( "#jquery-ajax-test" ).attr( "async" ), "async", "attr value" );
|
||||||
|
return xhr;
|
||||||
|
},
|
||||||
|
success: function() {
|
||||||
|
assert.ok( true, "success" );
|
||||||
|
},
|
||||||
|
complete: function() {
|
||||||
|
assert.ok( true, "complete" );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} );
|
||||||
|
|
||||||
ajaxTest( "jQuery.ajax() - execute JS when dataType option is provided", 3,
|
ajaxTest( "jQuery.ajax() - execute JS when dataType option is provided", 3,
|
||||||
function( assert ) {
|
function( assert ) {
|
||||||
return {
|
return {
|
||||||
create: function( options ) {
|
create: function( options ) {
|
||||||
|
Globals.register( "corsCallback" );
|
||||||
options.crossDomain = true;
|
options.crossDomain = true;
|
||||||
options.dataType = "script";
|
options.dataType = "script";
|
||||||
return jQuery.ajax( url( "mock.php?action=script&header=ecma" ), options );
|
return jQuery.ajax( url( "mock.php?action=script&header=ecma" ), options );
|
||||||
|
Loading…
Reference in New Issue
Block a user