Skip to content
New issue

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

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

Already on GitHub? # to your account

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

Open
chenlong-io opened this issue Apr 17, 2019 · 1 comment

Comments

@chenlong-io
Copy link

$('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 );
		}
	} );
};

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

No branches or pull requests

2 participants