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