envoi de message à l'extension chrome à partir d'une page web

Je veux envoyer un message de la console de la page Web aléatoire à mon extension chrome. chrome.extension.sendMessage ne semble pas fonctionner.

43
demandé sur Nakilon 2012-07-11 15:07:59

5 réponses

Selon les docs officielles, vous devez utiliser postMessage l'adresse de l'expéditeur et message écouteur d'événement dans le récepteur.

Voici un exemple:

La page de votre site web.html

var data = { type: "FROM_PAGE", text: "Hello from the webpage!" };
window.postMessage(data, "*");

Script de contenu: (injecté en utilisant chrome.tabs.executeScript(tabid, {code:...)

window.addEventListener("message", function(event) {
    // We only accept messages from ourselves
    if (event.source != window)
        return;

    if (event.data.type && (event.data.type == "FROM_PAGE")) {
        console.log("Content script received message: " + event.data.text);
    }
});

Ici page.html (qui ne fait pas partie de l'extension) publie des messages à lui-même, qui sont interceptés et inspectés par le script de contenu. L'inverse est possible grâce à similaire moyen.

Pour passer du script de contenu à l'extension, vous devrez utiliser l'une des techniques de transmission de messages disponibles .

, Il semble compliqué et c'est un peu compliqué, mais tout ce charabia est très sécurisé.

50
répondu Silviu-Marian 2017-02-22 14:09:30

Voici une citation de la dernière http://developer.chrome.com/extensions/messaging.html, C'est beaucoup plus simple pour soutenir ce genre de fonctionnalité maintenant, voici comment:

Envoi de messages à partir de pages web

Similaire à la messagerie Cross-extension, votre application ou extension peut recevoir et répondre aux messages des pages web régulières. Pour utiliser cette fonction, vous devez d'abord spécifier dans votre manifest.json Quel web les sites avec lesquels vous souhaitez communiquer. Pour exemple:

"externally_connectable": {
  "matches": ["*://*.example.com/*"]
}

Cela exposera L'API de messagerie à n'importe quelle page qui correspond à L'URL les modèles que vous spécifiez. Le modèle D'URL doit contenir au moins un domaine de deuxième niveau - c'est-à-dire, les modèles de nom d'hôte comme "", ".com", ".co.royaume-uni", et ".appspot.com" et sont interdits. Depuis la page web, utilisez le runtime.sendMessage ou runtime.connectez Api pour envoyer un message à une application ou une extension spécifique. Par exemple:

// The ID of the extension we want to talk to.
var editorExtensionId = "abcdefghijklmnoabcdefhijklmnoabc";

// Make a simple request:
chrome.runtime.sendMessage(editorExtensionId, {openUrlInEditor: url},
  function(response) {
    if (!response.success)
      handleError(url);
  });

Depuis votre application ou extension, vous pouvez écouter les messages de pages web via le moteur d'exécution.onMessageExternal ou runtime.API onConnectExternal, similaire à la messagerie Cross-extension. Seule la page web peut lancer un connexion. Voici un exemple:

chrome.runtime.onMessageExternal.addListener(
  function(request, sender, sendResponse) {
    if (sender.url == blacklistedWebsite)
      return;  // don't allow this web page access
    if (request.openUrlInEditor)
      openUrl(request.openUrlInEditor);
  });
31
répondu hewigovens 2018-07-02 00:08:02

Vous pouvez passer au contexte d'exécution JS de votre script de contenu en utilisant le menu <page context> au bas de la console js développeur d'une page, puis utiliser chrome.runtime.sendMessage et d'autres API chrome.* comme vous le feriez dans le script de contenu.

entrez la description de l'image ici

5
répondu jaredjacobs 2013-11-25 23:43:34

Donc, pour élaborer, un exemple plus concret: un problème avec le style chrome.runtime.sendMessage(...) est que vous devez spécifier le pag sur lequel vous êtes comme externally_connectable qui ne prend pas un caractère générique global comme " https:///". Donc, si vous voulez que la capacité, vous devez utiliser le postMessage style communication. Capturez le message de la fenêtre dans le contentscript, puis à partir du contentscript, vous pouvez l'envoyer ailleurs (si vous le souhaitez, comme au background.js etc.)

Donc dans la page Web normale, ou dans injecté source que vous intégrez dans la page normale, à partir de votre contentscript.js, envoyez un message comme ceci:

window.postMessage({ type: "FROM_PAGE_TO_CONTENT_SCRIPT", 
     text: "Hello from the webpage!" }, "*");

Ex, vous pouvez l'ajouter à un bouton comme ceci:

document.getElementById("theButton").addEventListener("click",
    function() {
       window.postMessage({ type: "FROM_PAGE_TO_CONTENT_SCRIPT", 
                            text: "Hello from the webpage!" }, "*");
}, false);

Puis pour le capturer dans le contentscript.js et "envoyer" pour le reste de l'extension, le seul inconvénient est que vous voulez seulement de "sélectionner" les messages qui semblent être ceux qui vous sont chers:

window.addEventListener("message", function(event) {
  // We only accept messages from this window to itself [i.e. not from any iframes]
  if (event.source != window)
    return;

  if (event.data.type && (event.data.type == "FROM_PAGE_TO_CONTENT_SCRIPT")) {        
    chrome.runtime.sendMessage(event.data); // broadcasts it to rest of extension, or could just broadcast event.data.payload...
  } // else ignore messages seemingly not sent to yourself
}, false);
4
répondu rogerdpack 2018-06-29 19:43:50

En plus de @hewigovens, Je n'ai pas assez de points à commenter... Je vous explique @ renatoargh et @ sbichenko Si vous envoyez un message à partir d'une page Web par défaut -

1) la page Web doit être citée dans le manifeste. par exemple:

"externally_connectable": {
  "matches": ["http://abcde/abcde/main.aspx*"]
}

2) l'arrière-plan.js (page de fond) sauf l'appel avec onMessageExternal par exemple (appel d'une extension):

var host_name = "com.my_chrome_extension.com";
 chrome.runtime.onMessageExternal.addListener(function(message, sender, sendResponse) {
    chrome.runtime.sendNativeMessage(host_name, {"run":message});
    sendResponse({"success": "success"});
    return true;
});
2
répondu AJ AJ 2016-05-15 09:52:47