2014-11-04 2 views
3

Я пишу расширение 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); 

Введенный Script

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 событие для ввода.

Все это работает. Однако, когда событие вызывает событие, он запускает currentItem.onclick() и пытается получить доступ к окну.listOfCourses, он не видит переменную. Я смущен, почему я больше не могу видеть свои глобальные переменные.

Любая помощь была бы принята с благодарностью!

ответ

5

Глобальные переменные сценария контента и сценарий с введенным на уровне страницы are isolated.

Скрипты содержания выполняются в специальной среде под названием изолированный мир. Они имеют доступ к DOM страницы, на которую они вводятся, но не любые переменные или функции JavaScript, созданные страницей. Он выглядит для каждого сценария контента так, как если бы на его запущенной странице не было другого исполняемого кода JavaScript. То же самое верно в обратном: JavaScript, запущенный на странице, не может вызывать какие-либо функции или обращаться к любым переменным, определенным сценариями контента.

Emphasis mine.

Чтобы передать данные в ваш скрипт контента, вам не нужно использовать дополнительные элементы 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); 

См this answer для гораздо большего количества деталей.

+0

Спасибо Xan, это именно то, что я искал! – chris75898

0

Над ответом может работать, но я не думаю, что это правильный путь ...

Во-первых:

Если вы уже опубликовали свой добавочный номер, получить ключ приложения и поместить его в свой явить "ключ", как описано here:

  • установить Chrome Extension Source Viewer
  • CRX -> источник расширения вид -> ввести опубликованный ар пликация URL -> введите
  • открытые инструменты разработчика (F12) -> перейти в консоль
  • скопировать "ключ" atring из консоли в локальном manifest.json:
    "ключ"

    : «MIIBIjANBgkqhkiG9w ...RwIDAQAB»,

Это обеспечит местное и опубликованное расширение имеют тот же extensionId

Второе:

  • загрузить ваше локальное расширение
  • узнать ваш extensionId, перейдя по адресу chrome://extensions и ищем идентификатор под вашим e XTension название

Третье:

в вашем фоне сценария (т.е. 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 с тем, который вы получили на втором этапе)

Смежные вопросы