2013-07-23 21 views
10

To jest the test case.alert() wywołany w nowym oknie wydaje się być wywołany z oryginalnej strony przy użyciu metod jQuery:

Korzystanie JavaScript:

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

daje to oczekiwanego rezultatu: alert dialogowe jest wyświetlane wewnątrz nowym oknie.

Korzystanie jQuery:

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

Alert dialogowe pokazane wewnątrz stronie głównej.

Dlaczego różnica? Czy coś mi umyka?

Zachowanie to zostało przetestowane w chrome/FF/Safari/IE

EDIT

Jak podkreślił mishik, to ze względu na to, jak jQuery obsługuje tagi skryptu metodą globalEval do uruchamiania skryptów w kontekście globalnym. Tak więc możliwe obejście przy użyciu jQuery (ale nie spaść z powrotem do czystego sposobu JavaScript) może być, aby ustawić zmienną w kontekście globalnym newwindow zbyt i używać go tak, na przykład:

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

DEMO

+0

+1 Czy to jest powód, dlaczego ludzie mówią, jQuery jest szybszy niż javascript? – Praveen

Odpowiedz

8

Wygląda na to, że jQuery obsługuje znacznik <script>.

domManip funkcja w kodzie źródłowym 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 obetnie wszystkie <script> elementy, oceniać je w kontekście globalnym, a następnie wyłączyć.

domManip jest wywoływana przez append() metody:

append: function() { 
    return this.domManip(arguments, function(elem) { 
+0

Hmmmm. Jak rozwiązać ten problem za pomocą jQuery? – Neal

+1

@Nie odwołanie do czystych metod JavaScript. – mishik

+0

+1 Ładne i szybkie badania. – Praveen