Расширение Chrome - передача объекта со страницы в контекстный скрипт
Я пишу расширение для Chrome и пытаюсь передать объект обратно с главной страницы в контекстный скрипт. Я не могу получить доступ к переменным окна.
ContextScript
//STORE DATA TO CHROME STORAGE ON EVENT
//create hidden input
var hiddenInput = document.createElement("input");
hiddenInput.setAttribute("type", "text");
hiddenInput.setAttribute("id", "__HIDDEN__RESULT__");
//add input to page
var currentItem = document.body.appendChild(hiddenInput);
//event to be fired on click
currentItem.onclick = function() {
//get the global variable window.listOfCourses and stick it in storage
chrome.storage.local.set({'dataVault' : window.listOfCourses});
};
//inject script into page
var s = document.createElement("script");
s.src = chrome.extension.getURL("gradebook.js");
s.onload = function() {this.parentNode.removeChild(this);};
(document.head||document.documentElement).appendChild(s);
Введенный скрипт
function processData()
{
window.listOfCourses = [];
for (i=0; i < window.completedData.length; i++)
{
//get data and add to window.listOfCourses
}
var myElement = document.getElementById("__HIDDEN__RESULT__")
myElement.click();
}
Внедренный скрипт извлекает информацию со страницы, помещает ее в объект, заданный как глобальная переменная, и, наконец, запускает событие onclick для ввода.
Все это работает. Однако, когда событие click запускается и запускает currentItem.onclick() и пытается получить доступ к window.listOfCourses, оно не видит переменную. Я запутался, почему я больше не могу видеть свои глобальные переменные.
Любая помощь будет принята с благодарностью!
2 ответа
Глобальные переменные скрипта контента и внедренного скрипта уровня страницы изолированы.
Сценарии содержимого выполняются в специальной среде, называемой изолированным миром. У них есть доступ к DOM страницы, в которую они внедрены, но не к каким-либо переменным или функциям JavaScript, созданным этой страницей. Каждый скрипт содержимого выглядит так, как будто на странице, на которой он запущен, нет другого JavaScript-кода. То же самое верно и в обратном: JavaScript, запущенный на странице, не может вызывать какие-либо функции или обращаться к любым переменным, определенным скриптами содержимого.
Акцент мой.
Чтобы передать данные в ваш контент-скрипт, вам не нужно использовать дополнительные элементы DOM. Вам просто нужны пользовательские события DOM.
// Content script
// Listen for the event
window.addEventListener("FromPage", function(evt) {
/* message is in evt.detail */
}, false);
// Page context
var message = {/* whatever */};
var event = new CustomEvent("FromPage", {detail: message});
window.dispatchEvent(event);
Смотрите этот ответ для более подробной информации.
Выше ответ может работать, но я не думаю, что это правильный путь...
Первый:
Если вы уже опубликовали свое расширение, получите ключ приложения и поместите его в свой "ключ" манифеста, как описано здесь:
- установить Chrome Extension Source Viewer
- CRX -> просмотреть источник расширения -> ввести URL опубликованного приложения -> ввести
- открыть инструменты разработчика (F12) -> перейти к консоли
скопируйте строку "key" из консоли в локальный файл manifest.json:
"ключ": "MIIBIjANBgkqhkiG9w...RwIDAQAB",
Это обеспечит одинаковое расширение вашего локального и опубликованного расширения.
Во- вторых:
- загрузить ваше локальное расширение
- узнайте свой внутренний номер, перейдя в
chrome://extensions
и ищет идентификатор под названием вашего внутреннего номера
В третьих:
в вашем фоновом скрипте (т.е. background.js) прослушайте сообщения вроде этого:
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.name === 'msg1') {
alert(message.key1);
}
});
в вашем скрипте содержимого (т.е. contentScript.js) отправьте сообщения типа этого:
chrome.runtime.sendMessage(extensionId, { name: 'msg1', key1: 'value1'}, undefined, (response) => {});
(замените extensionId на тот, который вы получили на втором шаге)