2012-05-30 4 views
15

Si è verificato un problema durante lo sviluppo di questo small userscript. Quando ho voluto bloccare ogni XMLHttpRequest dal sito Web in esecuzione con il mio script, non succedeva niente (almeno con Chrome):Perché window (e unsafeWindow) non sono gli stessi di un userscript come da un tag <script>?

function main() { 
    // Override XHR.open with a custom function 
    window.XMLHttpRequest.prototype.open = function() { 
    // Nothing... so it's supposed to block every xhr.open() call 
    } 
} 
main(); 

Stessa cosa quando si sostituisce window da unsafeWindow.

Tuttavia, quando ho usato questo piccolo trucco, tutto ha funzionato come un fascino:

// No more call to main(), and: 
var script = document.createElement("script"); 
script.textContent = "(" + main.toString() + ")();"; 
document.body.appendChild(script); 

Ogni chiamata a xhr.open è sostituita dalla mia funzione personalizzata, non più AJAX.

Quindi immagino che l'elemento window non sia lo stesso quando main viene chiamato dall'interno dello script rispetto a quando viene chiamato da un contenitore <script></script>. Qualcuno può spiegarmi perché?

risposta

44

Vedere "Are Chrome user-scripts separated from the global namespace like Greasemonkey scripts?". Sia gli script userscripts/content-script di Chrome che gli script Greasemonkey sono isolati dal javascript della pagina. Questo viene fatto per aiutarti a impedirti di essere hackerato, ma riduce anche i conflitti e gli effetti collaterali inaspettati.

Tuttavia, i metodi sono diversi per ogni browser ...

Firefox: gli script

  1. viene eseguito in an XPCNativeWrapper sandbox, a meno che non @grant none è in vigore (come di GM 1.0).
  2. Avvolge lo script in una funzione anonima per impostazione predefinita.
  3. Fornisce unsafeWindow per accedere al javascript della pagina di destinazione. Ma attenzione che è possibile per i webmaster ostili per seguire l'uso di unsafeWindow nel contesto del copione e quindi ottenere privilegi elevati con il pwn.

Chrome:

  1. esegue gli script in an "isolated world".
  2. Avvolge lo script in una funzione anonima.
  3. Rigorosamente blocca qualsiasi accesso al JS della pagina da parte dello script e viceversa.
    Le versioni recenti di Chrome forniscono ora un oggetto denominato unsafeWindow, per compatibilità molto limitata, ma questo oggetto non fornisce alcun accesso al JS della pagina di destinazione. È lo stesso di window nell'ambito dello script (che non è window nell'ambito della pagina).

Detto questo, la versione dello script che ha usato unsafeWindow dovrebbe funzionare su/in Firefox, se implementato correttamente. È potrebbe funzionare utilizzando the Tampermonkey extension su Chrome, ma non ho intenzione di ricontrollarlo al momento.

Quando lo fate "trucco" (var script = document.createElement("script"); ...), si sono iniettando codice nella pagina di destinazione. Ciò scavalca la sandbox ed è l'unico modo su un normale userscript di Chrome affinché uno script possa interagire con il JS della pagina.

vantaggi iniezione:

  1. L'unico modo per non Tampermonkey userscripts per accedere agli oggetti o funzioni fornite dalla pagina di destinazione.
  2. Quasi sempre completamente compatibile tra Chrome, Firefox, Opera, ecc. (IE è, come sempre, qualcos'altro.)
  3. Spesso più facile eseguire il debug dell'intero script; gli strumenti di sviluppo funzionano normalmente.

inconvenienti iniezione:

  1. Lo script, almeno le parti iniettate, non possono utilizzare i privilegi avanzati (in particolare dei domini) forniti dai GM_ funzioni - specialmente GM_xmlhttpRequest().
    Nota che attualmente Chrome supporta solo GM_addStyle, GM_xmlhttpRequest, GM_log e GM_openInTab, completamente, in modo nativo.
    Tampermonkey supporta quasi completamente le funzioni GM_.

  2. Può causare effetti collaterali o conflitti con il JS della pagina.

  3. L'utilizzo di librerie esterne introduce ancora più conflitti e problemi di temporizzazione. Non è neanche lontanamente facile come @require.
    @require, esegue anche il JS esterno da una copia locale, velocizzando l'esecuzione e quasi eliminando la dipendenza da un server esterno.

  4. La pagina può visualizzare, utilizzare, modificare o bloccare lo script.

  5. Richiede che JS sia abilitato. Firefox Greasemonkey, in particolare, può essere eseguito su una pagina che ha bloccato JS. Questo può essere una manna dal cielo su pagine gonfie, schifose e/o invadenti.

+2

Questa è una risposta inaspettata, lunga, precisa e informativa. Ho imparato molto, grazie! (e grazie per aver modificato il titolo della mia domanda) –

Problemi correlati