Manipulation: Respect script crossorigin attribute in DOM manipulation

Fixes gh-4542
Closes gh-4563

Co-authored-by: Michał Gołębiowski-Owczarek <m.goleb@gmail.com>
This commit is contained in:
高灰 2020-09-22 23:30:18 +08:00 committed by GitHub
parent df6858df2e
commit 15ae361485
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 63 additions and 3 deletions

View File

@ -157,7 +157,8 @@ function domManip( collection, args, callback, ignored ) {
// Optional AJAX dependency, but won't run scripts if not present
if ( jQuery._evalUrl && !node.noModule ) {
jQuery._evalUrl( node.src, {
nonce: node.nonce || node.getAttribute( "nonce" )
nonce: node.nonce || node.getAttribute( "nonce" ),
crossOrigin: node.crossOrigin
}, doc );
}
} else {

View File

@ -10,6 +10,7 @@ jQuery._evalUrl = function( url, options, doc ) {
cache: true,
async: false,
global: false,
scriptAttrs: options.crossOrigin ? { "crossOrigin": options.crossOrigin } : undefined,
// Only evaluate the response if it is successful (gh-4126)
// dataFilter is not invoked for failure responses, so using it instead

View File

@ -54,7 +54,21 @@ class MockServer {
} else {
header( 'Content-type: text/html' );
}
echo 'QUnit.assert.ok( true, "mock executed" );';
if ( !empty( $req->query['cors'] ) ) {
header( "Access-Control-Allow-Origin: *" );
}
if ( !empty( $req->query['callback'] ) ) {
$headers = array_combine(
array_map( 'strtolower', array_keys( $req->headers ) ),
array_values( $req->headers )
);
echo $req->query['callback'] . "(" . json_encode( [ 'headers' => $headers ] ) . ")";
} else {
echo 'QUnit.assert.ok( true, "mock executed" );';
}
}
// Used to be in test.js, but was renamed to testbar.php

View File

@ -67,7 +67,18 @@ var mocks = {
} else {
resp.writeHead( 200, { "content-type": "text/html" } );
}
resp.end( "QUnit.assert.ok( true, \"mock executed\" );" );
if ( req.query.cors ) {
resp.writeHead( 200, { "access-control-allow-origin": "*" } );
}
if ( req.query.callback ) {
resp.end( req.query.callback + "(" + JSON.stringify( {
headers: req.headers
} ) + ")" );
} else {
resp.end( "QUnit.assert.ok( true, \"mock executed\" );" );
}
},
testbar: function( req, resp ) {
resp.writeHead( 200 );

View File

@ -2295,6 +2295,39 @@ testIframe(
QUnit[ jQuery.ajax ? "test" : "skip" ]
);
// We need to simulate cross-domain requests with the feature that
// both 127.0.0.1 and localhost point to the mock http server.
// Skip the the test if we are not in localhost but make sure we run
// it in Karma.
QUnit[
jQuery.ajax && ( window.__karma__ || location.hostname === "localhost" ) ?
"test" :
"skip"
]( "jQuery.append with crossorigin attribute", function( assert ) {
assert.expect( 1 );
var done = assert.async(),
timeout;
Globals.register( "corsCallback" );
window.corsCallback = function( response ) {
assert.ok( typeof response.headers.origin === "string", "Origin header sent" );
window.clearTimeout( timeout );
done();
};
var src = baseURL + "mock.php?action=script&cors=1&callback=corsCallback";
src = src.replace( "localhost", "127.0.0.1" );
var html = "<script type=\"text/javascript\" src=\"" + src + "\" crossorigin=\"anonymous\"><\/script>";
jQuery( document.body ).append( html );
timeout = window.setTimeout( function() {
assert.ok( false, "Origin header should have been sent" );
done();
}, 2000 );
} );
QUnit.test( "jQuery.clone - no exceptions for object elements #9587", function( assert ) {
assert.expect( 1 );