10

这是测试用例

使用JavaScript

$('.js').on('click', function () {
    var newwindow = window.open();
    newwindow.document.write('<span>test</span>');
    newwindow.document.write('<scr' + 'ipt>alert(1)</scr' + 'ipt>');
});

这给出了预期的结果:对话框警报显示在新窗口中。

使用jQuery

$('.jquery').on('click', function () {
    var newwindow = window.open();
    $(newwindow.document.body).append('<span>test</span>', '<scr' + 'ipt>alert(1)</scr' + 'ipt>');
});

对话框警报显示在主页内。

为什么有区别?我在这里错过了什么吗?

此行为已在 chrome/FF/safari/IE 中进行了测试

编辑

正如mishik所指出的,这是由于 jQuery 处理脚本标签的方式,使用该globalEval方法在全局上下文中运行脚本。因此,使用 jQuery(但不回退到纯 JavaScript 方法)的一种可能解决方法是newwindow在全局上下文中设置变量并像这样使用它,例如:

$('.jquery').on('click', function () {
    newwindow = window.open();
    $(newwindow.document.body).append('<span>test</span>','<scr' + 'ipt>newwindow.window.alert(1)</scr' + 'ipt>');
});

演示

4

1 回答 1

8

似乎这是 jQuery 处理<script>标签的方式。

domManipjQuery源代码中的函数:

// Evaluate executable scripts on first document insertion
for ( i = 0; i < hasScripts; i++ ) {
    node = scripts[ i ];
    if ( rscriptType.test( node.type || "" ) &&
        !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) {

        if ( node.src ) {
            // Hope ajax is available...
            jQuery._evalUrl( node.src );
        } else {
            jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) );
        }
    }
}

domManip将剥离所有<script>元素,在全局上下文中评估它们,然后禁用。

domManip通过append()方法调用:

append: function() {
    return this.domManip( arguments, function( elem ) {
于 2013-07-23T15:30:44.797 回答