sendMessage z tła rozszerzenia lub wyskakującego okienka do skryptu zawartości nie działa

87

Wiem, że to pytanie było wielokrotnie zadawane na różne sposoby, ale próbowałem przejść przez wszystkie odpowiedzi (mam nadzieję, że nikogo nie przegapiłem) i żadna z nich nie zadziałała.

Oto kod mojego rozszerzenia:

oczywisty:

{
"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!");
  }
});

Dwa alerty strony w tle działają, a jeden z content_script nie.

komunikat dziennika konsoli: Błąd portu: nie można nawiązać połączenia. Koniec odbierający nie istnieje.

Gdzie moja wina?

Metro
źródło
Powinieneś używać chrome.tabs.sendMessage()do wysyłania wiadomości do skryptów zawartości, a nie chrome.extension.sendMessage().
apsillers,

Odpowiedzi:

141

Na swojej stronie w tle powinieneś zadzwonić

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

zamiast używać chrome.extension.sendMessagetak, jak obecnie.

chrome.tabsWariant wysyła wiadomości do skryptów treści, podczas gdy chrome.extensionfunkcja wysyła wiadomości do wszystkich innych komponentów rozszerzających.

apsillers
źródło
7
Dzięki Ci. Zgadza się, z wyjątkiem tego, że chrome.tabs.sendMessage musi określać, do której karty wysłać . Więc rozwiązaniem jest zmiana na:chrome.tabs.query({active: true}, function(tabs){ chrome.tabs.sendMessage(tab.id, {action: "open_dialog_box"}, function(response) { }); });
Subway
1
Ta odpowiedź mi pomogła. Dziękuję bardzo za tę przydatną odpowiedź.
Touhid
13
co napisać, aby otrzymać na content-script.js?
Kushal Jain
5
@KushalJain Właśnie to rozgryzłem. W pliku JS skryptu zawartości będziesz chciał dodać detektor zdarzeń w następujący sposób: chrome.runtime.onMessage.addListener( (message, sender, sendResponse) => { /* Code Here */ } ); messageto parametr zawierający { action: "open_dialog_box" }lub cokolwiek wysyłasz. senderto obiekt zawierający identyfikator rozszerzenia Chrome. sendResponseto parametr zawierający function(response) {}lub jakąkolwiek funkcję, którą przekazujesz, która ma zostać wywołana po obsłużeniu wiadomości.
jsea
5
To rozwiązanie nie zadziałało. Dokładnie postępuję zgodnie z dokumentacją. Skopiowałem cały kod z developer.chrome.com/extensions/messaging. To bardzo prosty przykład, ale nie mogłem go poprawnie wykonać. Pojawia się błąd Nie można nawiązać połączenia. Koniec odbierający nie istnieje. Wszelkie pomysły
umsateesh
1

@apsillers jest poprawne. Nie zapomnij również zwrócić wartości true w odbiorniku content-script, w przeciwnym razie może on zamknąć się zbyt wcześnie.

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
    console.log(message)
    return true
});
Ronan Ca
źródło
To naprawiło problem - nie otrzymałem odpowiedzi, ale dodanie return truesprawiło, że zadziałało.
rupertonline