99 votes

sendMessage à partir de l'arrière-plan de l'extension ou de la popup vers le contenu script ne fonctionne pas

Je sais que cette question a été posée à plusieurs reprises de différentes manières, mais j'ai essayé de passer en revue toutes les réponses (j'espère n'avoir oublié personne) et aucune n'a fonctionné pour moi.

Voici le code de mon extension :

manifeste :

{
"name": "test",
"version": "1.1",
"background": 
{ 
    "scripts": ["contextMenus.js"]
},

"permissions": ["tabs", "<all_urls>", "contextMenus"],

"content_scripts" : [
    {
        "matches" : [ "http://*/*" ],
        "js": ["jquery-1.8.3.js", "jquery-ui.js"],
        "css": [ "jquery-ui.css" ],
        "js": ["openDialog.js"]
    }
],

"manifest_version": 2
}

contextMenus.js

function onClickHandler(info, tab) {
    if (info.menuItemId == "line1"){

      alert("You have selected: " + info.selectionText);

      chrome.extension.sendMessage({action:'open_dialog_box'}, function(){});

      alert("Req sent?");

    }
}

chrome.contextMenus.onClicked.addListener(onClickHandler);

chrome.runtime.onInstalled.addListener(function() {

  chrome.contextMenus.create({"id": "line1", "type": "normal", "title": "I'm line 1",     "contexts":["selection"]});

});

openDialog.js

chrome.extension.onMessage.addListener(function(msg, sender, sendResponse) {

  if (msg.action == 'open_dialog_box') {
    alert("Message recieved!");
  }
});

Les deux alertes de la page de fond fonctionnent, alors que celle du content_script ne fonctionne pas.

message du journal de la console : Erreur de port : Impossible d'établir la connexion. L'extrémité réceptrice n'existe pas.

Où est ma faute ?

173voto

apsillers Points 29372

Dans votre page d'arrière-plan, vous devez appeler

chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
    chrome.tabs.sendMessage(tabs[0].id, {action: "open_dialog_box"}, function(response) {});  
});

au lieu d'utiliser chrome.extension.sendMessage comme vous le faites actuellement.

En chrome.tabs envoie des messages au contenu des scripts, alors que la variante chrome.extension envoie des messages à tous les autres composants de l'extension.

21voto

Ronan Ca Points 171

@apsillers a raison. N'oubliez pas non plus de retourner true dans votre écouteur content-script ou il pourrait se fermer trop tôt.

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
    console.log(message)
    return true
});

3voto

Voici un exemple d'un script d'arrière-plan qui envoie un message au fichier content-script.

background.js

chrome.tabs.sendMessage(tabs[0].id,"your message"); 

contenu-script/content.js

chrome.runtime.onMessage.addListener(function (response, sendResponse) {
          console.log(response);
});

2voto

Sal7_one Points 43

Le problème avec les solutions fournies est qu'elles soulèvent d'autres erreurs (qui cassent mon Google Chrome)

La solution de @apsillers fonctionne mais le callback soulève des erreurs !

A quoi cela devrait ressembler

// Background.js

chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
chrome.tabs.sendMessage(tabs[0].id, {action: "open_dialog_box"});  
});

Maintenant dans le contenu scripts tel que fourni par @Ronan Ca qui s'appuie sur la solution @apsillers. Il n'est pas idéal de revenir puisque nous avons retiré le callback du scripts de fond.

// ContentScripts.js

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
console.log(message)
// return true <- this and the callback in background.js are what caused a crash in extensions page of my Google chrome
});

La console en arrière-plan ne s'ouvre pas si j'essaie de le faire avec des callbacks. (Le crash est si grave que ça)

1voto

Nikita Jerschow Points 628

Mon cas d'utilisation nécessitait l'envoi d'un message à l'arrière-plan script à partir d'une page web. J'ai utilisé chrome.runtime.onMessageExternal pour attraper ce message.

À l'intérieur de cet écouteur, je faisais essentiellement suivre le message à mon contenu script pour qu'il puisse faire son travail, mais je n'arrivais pas à comprendre pourquoi mon contenu script onMessage listener ne capturait pas le message.

Il s'avère qu'en attendant 1 seconde avant d'envoyer le message depuis la page web (je le faisais essentiellement au chargement), j'ai pu voir le message frapper mon contenu script.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X