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が指摘したように、これはglobalEval、グローバル コンテキストでスクリプトを実行するメソッドを使用して、jQuery がスクリプト タグを処理する方法によるものです。したがって、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 に答える