Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

$('body').append('<script src="http://xxx.js"><\/ script>') src is invalid #1357

Open
Vibing opened this issue Apr 17, 2019 · 1 comment
Open

Comments

@Vibing
Copy link

Vibing commented Apr 17, 2019

$('body').append('<script src="http://xxx.js"><\/script>')

I tried to execute the above code but it did not send a request

@xudeming208
Copy link

xudeming208 commented Jun 11, 2020

我看了下zepto的源码,翻译过来其执行过程如下,所以不会发送网络请求:

	<div id="demo"></div>

	let str = '<script src="http://xxx.js"><\/script>';
	document.getElementById('demo').innerHTML = str;
	let dom = [].slice.call(document.getElementById('demo').childNodes)[0];
	document.body.insertBefore(dom, null)

但是zepto下面代码是可以执行的:

$('body').append('<script>console.log('test')<\/script>')

其实通过eval执行的,zepto源码如下:

if (parentInDocument) traverseNode(node, function (el) {
    if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' &&
        (!el.type || el.type === 'text/javascript') && !el.src) {
        var target = el.ownerDocument ? el.ownerDocument.defaultView : window
        target['eval'].call(target, el.innerHTML)
    }
})

zepto用append css是可以发送网络请求的,如同用原生的innerHTML可以发送网络请求一样,或许是因为浏览器的安全策略,毕竟JS可以执行代码:

$('body').append('<link href="xxx.css">')

而我查看jQuery源码发现,其之所以能发送网络请求,是因为其发送了ajax请求xxx.js,其源码如下:

// 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" )
	}, doc );
}


jQuery._evalUrl = function( url, options, doc ) {
	return jQuery.ajax( {
		url: url,

		// Make this explicit, since user can override this through ajaxSetup (#11264)
		type: "GET",
		dataType: "script",
		cache: true,
		async: false,
		global: false,

		// Only evaluate the response if it is successful (gh-4126)
		// dataFilter is not invoked for failure responses, so using it instead
		// of the default converter is kludgy but it works.
		converters: {
			"text script": function() {}
		},
		dataFilter: function( response ) {
			jQuery.globalEval( response, options, doc );
		}
	} );
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants