Alert(), вызываемое в новом окне, похоже, вызывается с исходной страницы, если использовать методы jQuery

Это тестовый сценарий.

Использование 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 обрабатывает теги script, используя метод 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>');
});

DEMO

Ответ 1

Похоже, именно так jQuery обрабатывает тег <script>.

domManip в исходном коде jQuery:

// 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 ) {