Расширение 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 на тот, который вы получили на втором шаге)

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