Extensión de Chrome: pasar el objeto de la página a la secuencia de comandos de contexto

Estoy escribiendo una extensión de Chrome y estoy luchando por pasar un objeto de la página principal al script de contexto. Parece que no puedo acceder a las variables de la ventana.

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); 

Guión Inyectado

 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(); } 

La secuencia de comandos inyectada extrae información de una página, la inserta en un conjunto de objetos como variable global y, finalmente, activa el evento onclick para la entrada.

Todo esto funciona Sin embargo, cuando el evento click desencadena y ejecuta currentItem.onclick () e intenta acceder a window.listOfCourses, no ve la variable. Estoy confundido por qué ya no puedo ver mis variables globales.

¡Cualquier ayuda sería muy apreciada!

Las variables globales de un script de contenido y un script insertado a nivel de página están aisladas .

Los scripts de contenido se ejecutan en un entorno especial llamado mundo aislado . Tienen acceso al DOM de la página en la que se insertan, pero no a las variables o funciones de JavaScript creadas por la página . Mira a cada script de contenido como si no hubiera otro JavaScript ejecutándose en la página en la que se está ejecutando. Lo mismo ocurre a la inversa: JavaScript que se ejecuta en la página no puede invocar ninguna función ni acceder a ninguna variable definida por las secuencias de comandos de contenido.

Énfasis mío

Para pasar los datos a su secuencia de comandos de contenido, no tiene que emplear elementos DOM adicionales. Solo necesitas eventos DOM personalizados.

 // 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); 

Vea esta respuesta para más detalles.

La respuesta anterior puede funcionar, pero no creo que sea la correcta …

Primero:

Si ya ha publicado su extensión, obtenga la clave de la aplicación y colóquela en su “clave” de manifiesto como se describe aquí :

  • instalar el Visor de fonts de extensiones de Chrome
  • CRX -> ver fuente de extensión -> ingresar URL de aplicación publicada -> ingresar
  • abrir herramientas de desarrollador (F12) -> ir a la consola
  • copie el atring “clave” de la consola en su manifest.json local:

    “clave”: “MIIBIjANBgkqhkiG9w … RwIDAQAB”,

Esto garantizará que su extensión local y publicada tenga la misma extensión ID

Segundo:

  • carga tu extensión local
  • descubra su extensionId yendo a chrome://extensions y buscando identificación debajo del título de su extensión

Tercero:

en tu script de fondo (es decir, background.js) escucha mensajes como este:

 chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { if (message.name === 'msg1') { alert(message.key1); } }); 

en su secuencia de comandos de contenido (es decir, contentScript.js) envíe mensajes de esta manera:

 chrome.runtime.sendMessage(extensionId, { name: 'msg1', key1: 'value1'}, undefined, (response) => {}); 

(reemplace extensionId con el que obtuvo en el segundo paso)