Как указано в Обзор расширений Chrome: архитектура (которую необходимо прочитать):
Если вашему расширению нужно взаимодействовать с веб-страницами, то ононужен скрипт контента. Скрипт контента - это некоторый JavaScript, который выполняется в контексте страницы, которая была загружена в браузер.Считайте, что скрипт содержимого является частью этой загруженной страницы, а не частью расширения, с которым он был упакован (его родительское расширение).
Всплывающее окно browserAction - это страница, которую вы видите, когда нажимаете значокна панели инструментов браузера это HTML-страница с URL-адресом chrome-extension://
, поэтому при доступе к ее DOM вы воздействуете на всплывающее окно.То же самое относится и к странице фона / опций расширения.
Для доступа к DOM веб-страницы и манипулирования им доступны два способа:
Либо объявите сценарий (и) содержимого в manifest.json и используйте сообщения :
chrome.tabs.sendMessage()
из фоновой / всплывающей страницы в прослушиватель chrome.runtime.onMessage
внедренного скрипта содержимого, который будет выполнять действия с веб-страницей и передавать результаты посредством sendResponse
обратного вызова согласно документации (примечание: только JSON-ifiableподдерживаются такие объекты, как числа, строки, массивы, простые объекты, что означает не элементы DOM, не классы и не функции).Если сценарий содержимого должен инициировать связь со страницей расширения, он должен использовать chrome.runtime.sendMessage()
.
Или использовать Tabs API для вставки скрипта содержимого :
chrome.tabs.executeScript(tabId, details, callback)
Требуется разрешения : "tabs"
, "https://www.example.com/*"
(или "<all_urls>"
и варианты, такие как "*://*/*"
, "http://*/*"
, "https://*/*"
)
В случае явной активации пользователя лучше использовать "activeTab"
разрешение вместо "tabs"
и "<all_urls>"
, поскольку оно служит альтернативой для многих вариантов использования "<all_urls>"
, но не отображает предупреждающее сообщение во время установки .
.executeScript()
может использоваться с функцией обратного вызова, которая получает массив последних оцененных выражений в сценарии с внедренным содержимым, по одному элементу на каждый кадр, в который он вводится на вкладке.Chrome использует JSON.parse()
и JSON.stringify()
для внутренних результатов, ограничивая поддерживаемые типы простыми объектами и простыми строковыми значениями, такими как число / строка или их массивы.
Так что он не работает для элементов, функций DOM,пользовательские свойства, методы получения / установки: вам нужно вручную отобразить / извлечь необходимые данные и передать их в виде простого массива / объекта.
Сценарии содержимого выполняются в специальной среде, называемой изолированным миром. Они имеют доступ к DOM страницы, в которую они внедрены, но не к любым переменным или функциям JavaScript, созданным этой страницей.Каждый скрипт содержимого выглядит так, как будто на странице, на которой он запущен, нет другого JavaScript-кода.То же самое верно и в обратном: JavaScript, работающий на странице, не может вызывать какие-либо функции или обращаться к любым переменным, определенным сценариями содержимого.
Все еще возможно пойти на более глубокий уровень и получить доступ к веб-странице JavaScriptпеременные / функции .
В качестве примера второго метода покажем, что div при нажатии действия браузера.
Мы будемиспользуйте chrome.tabs.executeScript()
в обработчике кликов browserAction
, чтобы внедрить файл сценария содержимого (или строку литерального кода, если он маленький, см. документацию метода) в DOM этой страницы.
var someVar = {text: 'test', foo: 1, bar: false};
chrome.tabs.executeScript({
code: '(' + function(params) {
document.body.insertAdjacentHTML('beforeend',
'<div style="all:unset; position:fixed; left:0; top:0; right:0; bottom:0;' +
'background-color:rgba(0,255,0,0.3)">' + params.text + '</div>'
);
return {success: true, html: document.body.innerHTML};
} + ')(' + JSON.stringify(someVar) + ');'
}, function(results) {
console.log(results[0]);
});
Как вы можете видеть, мы использовали автоматическое преобразование строки кода функции, чтобы иметь возможность писать введенный код как обычный JavaScript с подсветкой синтаксиса и линированием.Очевидным недостатком является то, что браузер тратит время на синтаксический анализ кода, но обычно это менее 1 миллисекунды, поэтому он незначителен.