web-dev-qa-db-fra.com

envoi d'un message à chrome à partir d'une page Web

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

46
dilpreet023

Selon les documents officiels vous devez utiliser postMessage dans l'expéditeur et message écouteur d'événements dans le récepteur .

Voici un exemple:

Page.html de votre site Web

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

Script de contenu: (injecté à l'aide de 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 qui sont interceptés et inspectés par le script de contenu. L'inverse est possible par des moyens similaires.

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

Cela semble compliqué et quelque peu compliqué, mais tout ce mumbo-jumbo est très sécurisé.

56
Silviu-Marian

Voici une citation de la dernière http://developer.chrome.com/extensions/messaging.html , il est beaucoup plus simple de prendre en charge ce type de fonctionnalité maintenant, voici comment:

Envoi de messages à partir de pages Web

Semblable à la messagerie inter-extensions, votre application ou extension peut recevoir et répondre aux messages des pages Web régulières. Pour utiliser cette fonctionnalité, vous devez d'abord spécifier dans votre manifest.json avec quels sites Web vous souhaitez communiquer. Par exemple:

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

Cela exposera l'API de messagerie à toute page qui correspond aux modèles d'URL que vous spécifiez. Le modèle d'URL doit contenir au moins un domaine de second niveau, c'est-à-dire des modèles de nom d'hôte tels que "", ". Com", ". Co.uk" et ". appspot.com "et <all_urls> sont interdits. À partir de la page Web, utilisez les API runtime.sendMessage ou runtime.connect 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);
  });

À partir de votre application ou de votre extension, vous pouvez écouter les messages des pages Web via les API runtime.onMessageExternal ou runtime.onConnectExternal, comme la messagerie inter-extensions. Seule la page Web peut établir une 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);
  });
46
hewigovens

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 en tant que connectable de manière externe qui ne prend pas un caractère générique global comme "https: // / ". Donc, si vous voulez cette capacité, vous devez utiliser la communication postMessagestyle . Capturez le message de la fenêtre dans le contentscript, puis du contentscript, vous pouvez l'envoyer ailleurs (si vous le souhaitez, comme dans le background.js etc.)

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

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

ex, vous pouvez l'ajouter à un bouton comme celui-ci:

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

Ensuite, pour le capturer dans le contentscript.js et "l'envoyer" au reste de l'extension, la seule mise en garde est que vous ne voulez "sélectionner" que les messages qui semblent vous intéresser:

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);
5
rogerdpack

Vous pouvez basculer vers le contexte d'exécution JS de votre script de contenu à l'aide de <page context> menu en bas de la console JS du développeur d'une page, puis utilisez chrome.runtime.sendMessage et autre chrome.* API comme vous le feriez dans le script de contenu.

enter image description here

5
jaredjacobs

En plus de @hewigovens, je n'ai pas assez de points pour commenter ... J'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) le background.js (page d'arrière-plan) exclut l'appel avec onMessageExternal, par ex. (appelant 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;
});
3
AJ AJ