Расширение Chrome - доступ к переменной документа/страницы из расширения

Я пытаюсь разработать расширение, которое работает только на указанных страницах. Если владелец страницы добавляет глобальную переменную в свой код (например, ACCEPT_STATS = true;), я хочу выполнить указанный код.

Я уже привязываю свою функцию к событию onload, я также нашел решение, как это сделать в Firefox:

var win = window.top.getBrowser().selectedBrowser.contentWindow;
if (typeof win.wrappedJSObject.ACCEPT_STATS !== 'undefined') {
    // code to run if global variable present
}

но я не мог сделать эту работу в Chrome. Есть ли какая-либо возможность получить доступ к глобальному переменному URL-адресу броузера Chrome?

Мой добавочный код вводится как content- script.

Ответ 1

Да, в том числе script на странице выполняется в изолированном контексте со страницы runtime script.

Тем не менее, можно обойти проблему изолированных миров, нажав inline script на контекст среды выполнения через тег script, добавленный к документу html. После этого встроенный script может создать пользовательское событие.

Включенный script в изолированном контексте может прослушивать это событие и отвечать на него соответствующим образом.

Таким образом, код в вашем включенном script будет выглядеть примерно так:

// inject code into "the other side" to talk back to this side;
var scr = document.createElement('script');
//appending text to a function to convert it src to string only works in Chrome
scr.textContent = '(' + function () { 
  var check = [do your custom code here];
  var event = document.createEvent("CustomEvent");  
  event.initCustomEvent("MyCustomEvent", true, true, {"passback":check});
  window.dispatchEvent(event); } + ')();'
//cram that sucker in 
(document.head || document.documentElement).appendChild(scr);
//and then hide the evidence as much as possible.
scr.parentNode.removeChild(scr);
//now listen for the message
window.addEventListener("MyCustomEvent", function (e) {
  var check = e.detail.passback;
  // [do what you need to here].
});

Ответ 2

Работающий на странице javascript работает в другом "изолированном мире", чем javascript, который вы вводите с использованием сценариев контента. Google Chrome сохраняет эти два мира по соображениям безопасности, и поэтому вы не можете просто читать window.XYZ в любом окне. Дополнительная информация о том, как работают изолированные миры: http://www.youtube.com/watch?v=laLudeUmXHM

Правильный способ реализации этого заключается в общении со страницей через API window.postMessage. Вот как я это сделаю:

  • Внесите содержимое script в каждую вкладку
  • Отправить сообщение на вкладку через window.postMessage
  • Если страница понимает это сообщение, оно отвечает правильно (снова через window.postMessage)
  • Содержимое script выполняет код, который необходимо выполнить.

НТН