2012-05-30 5 views
15

Estaba enfrentando un problema al desarrollar este small userscript. Cuando quería bloquear todos los XMLHttpRequest desde el sitio web funcionando con mi escritura, no pasaba nada (al menos con Chrome):¿Por qué windows (y unssafeWindow) no son lo mismo desde un usuario que con una etiqueta <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(); 

Lo mismo cuando se sustituye por windowunsafeWindow.

Sin embargo, cuando utilicé este pequeño truco, todo funcionó como un encanto:

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

Cada llamada a xhr.open se sustituye por mi función personalizada, no más de AJAX.

Supongo que el elemento window no es lo mismo cuando se llama a main desde el script que cuando se llama desde un contenedor <script></script>. ¿Puede alguien explicarme por qué?

Respuesta

44

Ver "Are Chrome user-scripts separated from the global namespace like Greasemonkey scripts?". Tanto los archivos de usuario/scripts de contenido de Chrome como los de Greasemonkey están aislados del javascript de la página. Esto se hace para evitar que lo pirateen, pero también reduce los conflictos y los efectos secundarios inesperados.

Sin embargo, los métodos son diferentes para cada navegador ...

Firefox:

  1. ejecuta los scripts de an XPCNativeWrapper sandbox, a menos que @grant none es, en efecto, (a partir de GM 1.0).
  2. Envuelve el script en una función anónima de forma predeterminada.
  3. Proporciona unsafeWindow para acceder al javascript de la página de destino. Pero tenga en cuenta que es posible para que los webmasters hostiles sigan el uso de unsafeWindow de vuelta al contexto del guión y así obtener privilegios elevados con los que pwn.

Chrome:

  1. ejecuta los scripts de an "isolated world".
  2. Envuelve el script en una función anónima.
  3. Strictly bloquea cualquier acceso a la página JS por el script y viceversa.
    Las versiones recientes de Chrome ahora proporcionan un objeto llamado unsafeWindow, para compatibilidad muy limitada, pero este objeto no proporciona ningún acceso al JS de la página de destino. Es lo mismo que window en el alcance del script (que no es window en el alcance de la página).

Dicho esto, la versión de su secuencia de comandos que utiliza unsafeWindow debería funcionar en/en Firefox si se aplica correctamente. Es podría funciona usando the Tampermonkey extension en Chrome, pero no voy a volver a verificar eso en este momento.

Cuando se hace esto "truco" (var script = document.createElement("script"); ...), que son inyectar código en la página de destino. Esto pasa por alto el entorno limitado y es la única forma en un usuario de Chrome normal para que un script interactúe con el JS de la página.

ventajas de inyección:

  1. La única manera para userscripts no Tampermonkey acceder a objetos o funciones proporcionadas por la página de destino.
  2. Casi siempre totalmente compatible entre Chrome, Firefox, Opera, etc. (IE es, como siempre, algo más.)
  3. A menudo es más fácil depurar todo el script; las herramientas de desarrollador funcionan normalmente.

inconvenientes de inyección:

  1. el guión, al menos las piezas inyectadas, no pueden utilizar los privilegios mejoradas (especialmente entre dominios) proporcionados por los GM_ funciones - especialmente GM_xmlhttpRequest().
    Tenga en cuenta que actualmente Chrome solo admite GM_addStyle, GM_xmlhttpRequest, GM_log y GM_openInTab, completamente, de forma nativa.
    Tampermonkey admite GM_ funciona casi por completo, sin embargo.

  2. Puede causar efectos secundarios o conflictos con el JS de la página.

  3. El uso de bibliotecas externas presenta aún más conflictos y problemas de temporización. No es tan fácil como @require.
    @require, también ejecuta el JS externo desde una copia local, lo que acelera la ejecución y casi elimina la dependencia de un servidor externo.

  4. La página puede ver, usar, cambiar o bloquear el script.

  5. Requiere JS para habilitarse. Firefox Greasemonkey, especialmente, puede ejecutarse en una página que tiene JS bloqueado. Esto puede ser enviado al cielo en páginas infladas, asquerosas o intrusivas.

+2

Esta es una respuesta inesperada, larga, precisa e informativa. ¡Aprendí mucho con eso, gracias! (y gracias por editar el título de mi pregunta) –

Cuestiones relacionadas