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

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

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();

То же самое при замене 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> контейнер. Может кто-нибудь объяснить мне, почему?

1 ответ

Решение

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

Тем не менее, методы разные для каждого браузера...

Fire Fox:

  1. Запускает сценарии в изолированной программной среде XPCNativeWrapper, если @grant none действует (по состоянию на GM 1.0).
  2. По умолчанию сценарий помещается в анонимную функцию.
  3. Обеспечивает unsafeWindow чтобы получить доступ к JavaScript на целевой странице. Но будьте осторожны, что враждебные веб-мастера могут следовать unsafeWindow использование обратно в контекст скрипта и, таким образом, получить повышенные привилегии для вас.

Хром:

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

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

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

Преимущества впрыска:

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

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

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

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

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

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

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

Другие вопросы по тегам