I'm tratando de acceder a la activeTab DOM contenido de mi popup. Aquí está mi manifiesto:
{
"manifest_version": 2,
"name": "Test",
"description": "Test script",
"version": "0.1",
"permissions": [
"activeTab",
"https://api.domain.com/"
],
"background": {
"scripts": ["background.js"],
"persistent": false
},
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
"browser_action": {
"default_icon": "icon.png",
"default_title": "Chrome Extension test",
"default_popup": "index.html"
}
}
I'm realmente confundido si las secuencias de comandos de fondo (páginas de eventos con persistencia: false) o content_scripts son el camino a seguir. He leído toda la documentación y otros mensajes SO y todavía no tiene sentido para mí.
¿Puede alguien explicar por qué debo usar uno sobre el otro.
Aquí está el background.js que he estado probando:
chrome.extension.onMessage.addListener(
function(request, sender, sendResponse) {
// LOG THE CONTENTS HERE
console.log(request.content);
}
);
Y yo'sólo estoy ejecutando esto desde la consola emergente:
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.sendMessage(tab.id, { }, function(response) {
console.log(response);
});
});
Estoy recibiendo:
Port: Could not establish connection. Receiving end does not exist.
ACTUALIZACIÓN:
{
"manifest_version": 2,
"name": "test",
"description": "test",
"version": "0.1",
"permissions": [
"tabs",
"activeTab",
"https://api.domain.com/"
],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
],
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
"browser_action": {
"default_icon": "icon.png",
"default_title": "Test",
"default_popup": "index.html"
}
}
content.js
chrome.extension.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.text && (request.text == "getDOM")) {
sendResponse({ dom: document.body.innertHTML });
}
}
);
popup.html
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.sendMessage(tab.id, { action: "getDOM" }, function(response) {
console.log(response);
});
});
Cuando lo ejecuto, me sigue apareciendo el mismo error:
undefined
Port: Could not establish connection. Receiving end does not exist. lastError:30
undefined
Los términos "página de fondo", "ventana emergente", "script de contenido" siguen confundiéndote; te sugiero encarecidamente que eches un vistazo más en profundidad a la Documentación de extensiones de Google Chrome.
En cuanto a tu pregunta de si los scripts de contenido o las páginas de fondo son el camino a seguir:
Scripts de contenido: Definitivamente Los scripts de contenido son el único componente de una extensión que tiene acceso al DOM de la página web.
Página de fondo / Ventana emergente: Tal vez (probablemente como máximo 1 de los dos) Puede que necesite que el script de contenido pase el contenido DOM a una página de fondo o a la ventana emergente para su posterior procesamiento.
¡Permítanme repetir que recomiendo encarecidamente un estudio más cuidadoso de la documentación disponible!
Dicho esto, aquí hay un ejemplo de extensión que recupera el contenido DOM en las páginas de StackOverflow y lo envía a la página de fondo, que a su vez lo imprime en la consola:
background.js:
// Regex-pattern to check URLs against.
// It matches URLs like: http[s]://[...]stackoverflow.com[...]
var urlRegex = /^https?:\/\/(?:[^./?#]+\.)?stackoverflow\.com/;
// A function to use as callback
function doStuffWithDom(domContent) {
console.log('I received the following DOM content:\n' + domContent);
}
// When the browser-action button is clicked...
chrome.browserAction.onClicked.addListener(function (tab) {
// ...check the URL of the active tab against our pattern and...
if (urlRegex.test(tab.url)) {
// ...if it matches, send a message specifying a callback too
chrome.tabs.sendMessage(tab.id, {text: 'report_back'}, doStuffWithDom);
}
});
content.js:
// Listen for messages
chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
// If the received message has the expected format...
if (msg.text === 'report_back') {
// Call the specified callback, passing
// the web-page's DOM content as argument
sendResponse(document.all[0].outerHTML);
}
});
manifest.json:
{
"manifest_version": 2,
"name": "Test Extension",
"version": "0.0",
...
"background": {
"persistent": false,
"scripts": ["background.js"]
},
"content_scripts": [{
"matches": ["*://*.stackoverflow.com/*"],
"js": ["content.js"]
}],
"browser_action": {
"default_title": "Test Extension"
},
"permissions": ["activeTab"]
}
Usted don't tiene que utilizar el paso de mensajes para obtener o modificar DOM. He utilizado chrome.tabs.executeScript
en su lugar. En mi ejemplo estoy usando solo el permiso activeTab, por lo tanto el script se ejecuta solo en la pestaña activa.
parte del manifest.json
"browser_action": {
"default_title": "Test",
"default_popup": "index.html"
},
"permissions": [
"activeTab",
"<all_urls>"
]
index.html
<!DOCTYPE html>
<html>
<head></head>
<body>
<button id="test">TEST!</button>
<script src="test.js"></script>
</body>
</html>
test.js
document.getElementById("test").addEventListener('click', () => {
console.log("Popup DOM fully loaded and parsed");
function modifyDOM() {
//You can play with your DOM here or check URL against your regex
console.log('Tab script:');
console.log(document.body);
return document.body.innerHTML;
}
//We have permission to access the activeTab, so we can call chrome.tabs.executeScript:
chrome.tabs.executeScript({
code: '(' + modifyDOM + ')();' //argument here is a string but function.toString() returns function's code
}, (results) => {
//Here we have just the innerHTML and not DOM structure
console.log('Popup script:')
console.log(results[0]);
});
});
Para aquellos que intentaron gkalpak respuesta y no funcionó,
Tenga en cuenta que Chrome agregará la secuencia de comandos de contenido a una página necesaria sólo cuando su extensión habilitada durante el lanzamiento de cromo y también una buena idea reiniciar el navegador después de hacer estos cambios