google-chrome-extension

google chrome extension - Acceda a las variables js globales desde js inyectadas por una extensión de Chrome



google-chrome-extension (1)

Dado que no se puede acceder directamente a las variables JS de la página desde una extensión, debe insertar código en el elemento del script para que se ejecute en el contexto de la página y transmita la variable al script de contenido a través de mensajes DOM. Luego, el script de contenido puede transmitir el mensaje al iframe.

  • guión de contenido:

    runInPage(initConfigExtractor); chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { switch (msg) { case ''toggle'': toggle(); return; case ''getConfig'': window.addEventListener(chrome.runtime.id + ''-config'', event => { sendResponse(event.detail); }, {once: true}); window.dispatchEvent(new Event(chrome.runtime.id)); return true; } }) function initConfigExtractor(extensionId) { window.addEventListener(extensionId, () => { window.dispatchEvent(new CustomEvent(extensionId + ''-config'', { detail: window.config, })); }); } function runInPage(fn) { const script = document.createElement(''script''); document.head.appendChild(script).text = ''((...args) => ('' + fn + '')(...args))('' + JSON.stringify(chrome.runtime.id) + '')''; script.remove(); }

  • secuencia de comandos de iframe:

    function handler() { chrome.tabs.getCurrent(tab => { chrome.tabs.sendMessage(tab.id, ''getConfig'', config => { console.log(config); // do something with config }); }); }

  • caso alternativo - script emergente:

    function handler() { chrome.tabs.query({active: true, currentWindow: true}, tabs => { chrome.tabs.sendMessage(tabs[0].id, ''getConfig'', config => { console.log(config); // do something with config }); }); }

Así que básicamente:

  1. el script de iframe obtiene su propia identificación de pestaña y envía un mensaje al script de contenido
  2. el script de contenido envía un mensaje DOM a un script de página insertado previamente
  3. el script de la página escucha ese mensaje DOM y envía otro mensaje DOM al script de contenido
  4. el script de contenido lo envía en respuesta al script de iframe.

Todo es asíncrono, por lo que se necesitaba return true en el escucha de onMessage para mantener abierto el canal de mensajes.

Estoy tratando de crear una extensión que tendrá un panel lateral. Este panel lateral tendrá botones que realizarán acciones en función del estado de la página del host.

Seguí este ejemplo para inyectar el panel lateral y puedo conectar un botón al oyente Click. Sin embargo, no puedo acceder a la variable global js. En la consola del desarrollador, en el ámbito de la página de host puedo ver la variable (nombre de variable - config) que busco. pero cuando el contexto del panel lateral (popup.html) aparece el siguiente error:
VM523: 1 Error de referencia no capturado: la configuración no está definida. Parece que popup.html también se ejecuta en un hilo separado.

¿Cómo puedo acceder a la variable global js para el controlador onClick de mi botón?

Mi código:

manifest.json

{ "manifest_version": 2, "name": "Hello World", "description": "This extension to test html injection", "version": "1.0", "content_scripts": [{ "run_at": "document_end", "matches": [ "https://*/*", "http://*/*" ], "js": ["content-script.js"] }], "browser_action": { "default_icon": "icon.png" }, "background": { "scripts":["background.js"] }, "permissions": [ "activeTab" ], "web_accessible_resources": [ "popup.html", "popup.js" ] }

background.js

chrome.browserAction.onClicked.addListener(function(){ chrome.tabs.query({active: true, currentWindow: true}, function(tabs){ chrome.tabs.sendMessage(tabs[0].id,"toggle"); }) });

content-script.js

chrome.runtime.onMessage.addListener(function(msg, sender){ if(msg == "toggle"){ toggle(); } }) var iframe = document.createElement(''iframe''); iframe.style.background = "green"; iframe.style.height = "100%"; iframe.style.width = "0px"; iframe.style.position = "fixed"; iframe.style.top = "0px"; iframe.style.right = "0px"; iframe.style.zIndex = "9000000000000000000"; iframe.frameBorder = "none"; iframe.src = chrome.extension.getURL("popup.html") document.body.appendChild(iframe); function toggle(){ if(iframe.style.width == "0px"){ iframe.style.width="400px"; } else{ iframe.style.width="0px"; } }

popup.html

<head> <script src="popup.js"> </script> </head> <body> <h1>Hello World</h1> <button name="toggle" id="toggle" >on</button> </body>

popup.js

document.addEventListener(''DOMContentLoaded'', function() { document.getElementById("toggle").addEventListener("click", handler); }); function handler() { console.log("Hello"); console.log(config); }