J'essaie d'accéder au contenu du domaine ActiveTab à partir de ma fenêtre contextuelle. Voici mon manifeste:
{
"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"
}
}
Je ne comprends vraiment pas si les scripts en arrière-plan (pages d'événement avec persistance: false) ou les scripts de contenu sont la solution. J'ai lu toute la documentation et d'autres SO articles et cela n'a toujours aucun sens pour moi.
Quelqu'un peut-il expliquer pourquoi je pourrais utiliser l'un sur l'autre.
Voici le fichier background.js que j'ai essayé:
chrome.extension.onMessage.addListener(
function(request, sender, sendResponse) {
// LOG THE CONTENTS HERE
console.log(request.content);
}
);
Et je suis en train de l'exécuter depuis la console popup:
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.sendMessage(tab.id, { }, function(response) {
console.log(response);
});
});
Je suis en train:
Port: Could not establish connection. Receiving end does not exist.
PDATE:
{
"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);
});
});
Quand je le lance, j'obtiens toujours la même erreur:
undefined
Port: Could not establish connection. Receiving end does not exist. lastError:30
undefined
Les termes "page d'arrière-plan", "popup", "script de contenu" vous déroutent encore; Je suggère fortement de jeter un œil plus en profondeur sur la documentation de Google Chrome extensions.
Concernant votre question si les scripts de contenu ou les pages d’arrière-plan sont la voie à suivre:
Scripts de contenu : définitivement
Les scripts de contenu sont le seul composant d’une extension ayant accès au DOM de la page Web.
Page d'arrière-plan/Popup : Peut-être (probablement au maximum 1 des deux)
Le script de contenu devra peut-être transmettre le contenu du DOM à une page d’arrière-plan ou à la fenêtre contextuelle pour un traitement ultérieur.
Permettez-moi de répéter que je recommande vivement une étude plus minutieuse de la documentation disponible!
Cela dit, voici un exemple d'extension qui récupère le contenu du DOM sur les pages StackOverflow et l'envoie à la page d'arrière-plan, qui l'imprime à son tour dans la console:
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"]
}
Il n'est pas nécessaire d'utiliser le message en passant pour obtenir ou modifier DOM. J'ai utilisé chrome.tabs.executeScript
instead. Dans mon exemple, j'utilise uniquement l'autorisation activeTab. Par conséquent, le script est exécuté uniquement sur l'onglet actif.
partie de 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]);
});
});
Pour ceux qui ont essayé gkalpak répondre et cela n'a pas fonctionné,
sachez que chrome ajoutera le script de contenu à une page nécessaire uniquement lorsque votre extension sera activée lors du lancement de chrome et qu'il est également judicieux de redémarrer le navigateur une fois ces modifications apportées.