Почему окно (и unsafeWindow) не совпадает с именем пользователя из тега <script>?

У меня возникла проблема при разработке этого небольшого usercript. Когда я хотел заблокировать каждый XMLHttpRequest с работающего сайта с помощью script, ничего не происходило (по крайней мере, с Chrome):

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

То же самое при замене window на unsafeWindow.

Однако, когда я использовал этот маленький трюк, все работало как шарм:

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

Каждый вызов xhr.open заменяется моей пользовательской функцией, не более AJAX.

Итак, я думаю, что элемент window не тот же, когда main вызывается из script, чем при вызове из контейнера <script></script>. Может кто-нибудь объяснить мне, почему?

Ответ 1

См. Являются ли пользовательские скрипты Chrome отделенными от глобального пространства имен, например скриптами Greasemonkey?. Оба Chrome userscripts/content-scripts и сценарии Greasemonkey изолированы от страницы javascript. Это делается для того, чтобы помочь вам избежать взлома, но также уменьшает конфликты и неожиданные побочные эффекты.

Однако для каждого браузера эти методы различны...

Firefox:

  • Запускает скрипты в песочнице XPCNativeWrapper, если @grant none действует (начиная с GM 1.0).
  • По умолчанию обходит script анонимную функцию.
  • Предоставляет unsafeWindow доступ к javascript целевой страницы. Но будьте осторожны, чтобы враждебные веб-мастера могли использовать unsafeWindow использование контекста script и, таким образом, получить повышенные привилегии для pwn you.

Chrome:

  • Запускает скрипты в "изолированном мире" .
  • Обтекает script анонимной функцией.
  • Строго блокирует любой доступ к странице JS с помощью script и наоборот.
    Последние версии Chrome теперь предоставляют объект с именем unsafeWindow, для очень ограниченной совместимости, но этот объект не предоставляет никакого доступа к целевой странице JS. Это то же самое, что и window в области script (которая не является window в области страницы).

Тем не менее, версия вашего script, которая использовала unsafeWindow, должна работать в/в Firefox, если она выполнена правильно. Он может работать с расширением Tampermonkey в Chrome, но я не буду сейчас проверять его дважды.

Когда вы выполняете этот "трюк" (var script = document.createElement("script"); ...), вы нажимаете нажимать на целевую страницу. Это обходит песочницу и является единственным способом в обычном браузере Chrome для script взаимодействовать со страницей JS.

Преимущества для инъекций:

  • Единственный способ, с помощью которого пользовательские скрипты, не относящиеся к Tampermonkey, получить доступ к объектам или функциям, предоставленным целевой страницей.
  • Почти всегда полностью совместим Chrome, Firefox, Opera и т.д. (IE, как всегда, что-то еще.)
  • Часто проще отлаживать весь script; инструменты разработчика работают нормально.

Недостатки впрыска:

  • script, по крайней мере, вложенные части, не могут использовать расширенные привилегии (особенно междоменные), предоставляемые функциями GM_, особенно GM_xmlhttpRequest().
    Обратите внимание, что в настоящее время Chrome поддерживает только GM_addStyle, GM_xmlhttpRequest, GM_log и GM_openInTab, полностью, изначально.
    Тем не менее Tampermonkey поддерживает функции GM_ почти полностью.

  • Может вызывать побочные эффекты или конфликты со страницей JS.

  • Использование внешних библиотек приводит к еще большему количеству конфликтов и проблем времени. Это не так просто, как @require.
    @require также запускает внешний JS из локального выполнения копирования, но все же исключает зависимость от внешнего сервера.

  • Страница может видеть, использовать, изменять или блокировать script.

  • Требуется включить JS. Firefox Greasemonkey, особенно, может работать на странице с заблокированным JS. Это может быть находкой на раздутых, дерьмовых и/или навязчивых страницах.