aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author高灰 <www@zeroplace.cn>2020-09-22 23:30:18 +0800
committerGitHub <noreply@github.com>2020-09-22 17:30:18 +0200
commit15ae361485056b236a9484a185238f992806e1ff (patch)
tree1826adb493e9276b1c49289e6a1e9ee4239f0c34
parentdf6858df2ed3fc5c424591a5e09b900eb4ce0417 (diff)
downloadjquery-15ae361485056b236a9484a185238f992806e1ff.tar.gz
jquery-15ae361485056b236a9484a185238f992806e1ff.zip
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>
-rw-r--r--src/manipulation.js3
-rw-r--r--src/manipulation/_evalUrl.js1
-rw-r--r--test/data/mock.php16
-rw-r--r--test/middleware-mockserver.js13
-rw-r--r--test/unit/manipulation.js33
5 files changed, 63 insertions, 3 deletions
diff --git a/src/manipulation.js b/src/manipulation.js
index 8eca61add..7838e2293 100644
--- a/src/manipulation.js
+++ b/src/manipulation.js
@@ -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 {
diff --git a/src/manipulation/_evalUrl.js b/src/manipulation/_evalUrl.js
index 0f7559ff0..8a8d63d9d 100644
--- a/src/manipulation/_evalUrl.js
+++ b/src/manipulation/_evalUrl.js
@@ -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
diff --git a/test/data/mock.php b/test/data/mock.php
index b76fd521c..24302e6bc 100644
--- a/test/data/mock.php
+++ b/test/data/mock.php
@@ -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
diff --git a/test/middleware-mockserver.js b/test/middleware-mockserver.js
index b3f630dd5..863aaf6bd 100644
--- a/test/middleware-mockserver.js
+++ b/test/middleware-mockserver.js
@@ -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 );
diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js
index a4a46f924..9058c1649 100644
--- a/test/unit/manipulation.js
+++ b/test/unit/manipulation.js
@@ -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 );