google chrome - make - Extensión de Chrome Devpanel Comunicación con la página de fondo
how to do a chrome extension (1)
Tengo una extensión para el panel cromo devtools. Puedo enviar mensajes a la página usando chrome.devtools.inspectedWindow.eval
... pero ¿cómo recibo los mensajes en el panel de desarrollo? Específicamente, necesito mi devpanel para conectarme a los eventos que suceden en la página. No puedo escuchar los eventos en mi script de contenido, ni la página de fondo.
chrome.extension.sendMessage
en el script de contenido, junto con chrome.extension.onMessage.addListener
en el script del panel de desarrollo. Pero sendMessage
queja de un Port error: Could not establish connection. Receiving end does not exist.
Port error: Could not establish connection. Receiving end does not exist.
El problema persiste con conexiones de larga duración:
En la secuencia de comandos de contenido o página de fondo:
var port = chrome.extension.connect({name: "test"});
port.postMessage({msg: "testing"});
En el panel de herramientas de desarrollo javascript:
chrome.extension.onConnect.addListener(function(port) {
port.onMessage.addListener(function(msg) {
// never gets here
});
});
¿Cómo puedo escuchar los eventos que se desencadenan en mi script de contenido-- en mi panel de herramientas de desarrollo? Un diagrama como este del Add-On SDK de Firefox sería genial: https://addons.mozilla.org/en-US/developers/docs/sdk/latest/static-files/media/content-scripting-overview.png
El objetivo es crear un canal ("puerto") para la comunicación. No importa cómo se cree el puerto, siempre que la conexión se mantenga correctamente.
La secuencia de comandos devtools debe iniciar el puerto, porque la secuencia de comandos de fondo no sabe cuándo se crea un panel devtools.
Aquí hay un ejemplo básico, que muestra un método de comunicación bidireccional:
devtools.js
chrome.devtools.panels.create(''Test'', ''/icon.png'', ''/panel.html'', function(extensionPanel) {
var _window; // Going to hold the reference to panel.html''s `window`
var data = [];
var port = chrome.runtime.connect({name: ''devtools''});
port.onMessage.addListener(function(msg) {
// Write information to the panel, if exists.
// If we don''t have a panel reference (yet), queue the data.
if (_window) {
_window.do_something(msg);
} else {
data.push(msg);
}
});
extensionPanel.onShown.addListener(function tmp(panelWindow) {
extensionPanel.onShown.removeListener(tmp); // Run once only
_window = panelWindow;
// Release queued data
var msg;
while (msg = data.shift())
_window.do_something(msg);
// Just to show that it''s easy to talk to pass a message back:
_window.respond = function(msg) {
port.postMessage(msg);
};
});
});
Ahora, el panel es capaz de enviar / recibir mensajes a través de un puerto. El script del panel (archivo de script externo, debido al CSP ) puede verse así:
panel.js
function do_something(msg) {
document.body.textContent += ''/n'' + msg; // Stupid example, PoC
}
document.documentElement.onclick = function() {
// No need to check for the existence of `respond`, because
// the panel can only be clicked when it''s visible...
respond(''Another stupid example!'');
};
Ahora, el script de la página de fondo:
background.js
var ports = [];
chrome.runtime.onConnect.addListener(function(port) {
if (port.name !== "devtools") return;
ports.push(port);
// Remove port when destroyed (eg when devtools instance is closed)
port.onDisconnect.addListener(function() {
var i = ports.indexOf(port);
if (i !== -1) ports.splice(i, 1);
});
port.onMessage.addListener(function(msg) {
// Received message from devtools. Do something:
console.log(''Received message from devtools page'', msg);
});
});
// Function to send a message to all devtools.html views:
function notifyDevtools(msg) {
ports.forEach(function(port) {
port.postMessage(msg);
});
}
Para probar, simplemente ejecute notifyDevtools(''Foo'');
en la página de fondo (por ejemplo, a través de la consola ). En esta demostración, el mensaje se enviará a todos los devtools. Una vez recibido, el panel devtools contendrá el mensaje recibido.
Coloque la extensión usando:
manifest.json
{ "name": "Test",
"manifest_version": 2,
"version": "1",
"devtools_page": "devtools.html",
"background":{"scripts":["background.js"]}
}
panel.html
<script src="panel.js"></script> <!-- Doctype etc not added for conciseness-->
devtools.html
<script src="devtools.js"></script>
Ver también
- ¿Cómo modificar el contenido en un panel devtools en una extensión de Chrome?
- API de
chrome.devtools
- Mensaje que pasa: conexiones de larga vida
- Política de seguridad de contenido en las extensiones de Chrome ("JavaScript en línea (...) no se ejecutará. Esta restricción prohíbe tanto los bloques de
<script>
línea como los manejadores de eventos en línea").