Код расширения Chrome против контентных скриптов против внедренных скриптов - PullRequest
54 голосов
/ 29 марта 2012

Я пытаюсь заставить мое расширение Chrome запускать функцию init() всякий раз, когда загружается новая страница, но у меня возникают проблемы при попытке понять, как это сделать. Из того, что я понимаю, мне нужно сделать следующее в background.html:

  1. Используйте chrome.tabs.onUpdated.addListener(), чтобы проверить, когда страница изменено
  2. Используйте chrome.tabs.executeScript для запуска скрипта.

У меня есть код:

//background.html
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
    chrome.tabs.executeScript(null, {code:"init();"});
});

//script.js
function init() {
    alert("It works!");
}

Мне также интересно, будет ли функция init () иметь доступ к моим другим функциям, расположенным в других файлах JS?

1 Ответ

157 голосов
/ 29 марта 2012

Код JavaScript в расширениях Chrome можно разделить на следующие группы:

  • Добавочный код - полный доступ ко всем разрешенным chrome.* API.
    Это включает фоновую страницу и все страницы, которые имеют прямой доступ к ней через chrome.extension.getBackgroundPage(), такие как всплывающие окна браузера .

  • Сценарии содержимого (через файл манифеста или chrome.tabs.executeScript) - Частичный доступ к некоторым из chrome API , полный доступ к DOM страницы (, а не к любому из window объектов, включая фреймы).
    Сценарии содержимого выполняются в области между расширением и страницей. Глобальный объект window сценария Content отличается от глобального пространства имен страницы / расширения.

  • Внедренные сценарии (через этот метод в сценарии содержимого) - Полный доступ ко всем свойствам на странице. Нет доступа ни к одному из chrome.* API.
    Внедренные сценарии ведут себя так, как если бы они были включены самой страницей, и никак не связаны с расширением. См. этот пост , чтобы узнать больше информации о различных методах инъекций.

Для отправки сообщения из внедренного сценария в сценарий содержимого необходимо использовать события. См. этот ответ для примера. Примечание. Сообщения, передаваемые внутри расширения из одного контекста в другой, автоматически (JSON) -сериализуются и анализируются .


В вашем случае код на фоновой странице (chrome.tabs.onUpdated), вероятно, вызывается перед оценкой скрипта содержимого script.js. Итак, вы получите ReferenceError, потому что init нет.

Кроме того, когда вы используете chrome.tabs.onUpdated, убедитесь, что вы проверили, полностью ли загружена страница, потому что событие запускается дважды: перед загрузкой и при завершении:

//background.html
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
    if (changeInfo.status == 'complete') {
        // Execute some script when the page is fully (DOM) ready
        chrome.tabs.executeScript(null, {code:"init();"});
    }
});
...