1

Ich versuche, eine Nachricht von Addon (Webextension) zu einer HTML-Seite, die im Addon ist zu senden. Die Webextension-API verwendet die Chrome-Oberfläche, die mit dem Chrome-Browser kompatibel ist. Ich benutze Firefox 48 Beta.Warum kann die Addon-Seite keine Nachricht empfangen?

Dies ist der Hintergrund-Skript (die „initiate-Seite“ Nachricht ist wichtig):

chrome.runtime.onMessage.addListener( 
    function(package, sender 
    ){ 
    switch (package.message){ 
     case "open": 
     if (package.subject == "tab") 
      { 
      win = myNamespace.tabs[package.module]; 
      result = win ? false : true; 

      if (result) 
      chrome.tabs.create(
       {"url": package.url }, 
       function(tab) {   
       if (chrome.extension.lastError) 
        console.log(chrome.extension.lastError); 
       else 
        myNamespace.tabs[package.module] = tab.id; 
       chrome.tabs.onRemoved.addListener(
        function(tabId, removeInfo)      
        { 
        for (var k in myNamespace.tabs) 
         { 
         if (tabId === myNamespace.tabs[k]) 
         { 
         myNamespace.tabs[k] = null; 
         break; 
         } 
         } 
        } 
       ); 
       } 
      ); 
      } 
     break; 
     case "initiate-page": 
     if (package.subject == "html-add-listeners") 
      { 
      switch(package.module){ 
      case "easy_options": 
      case "advanced_options": 
      case "images_options":    
      chrome.tabs.sendMessage(
       package.sender.id, 
       { message:"initiate-page-response", 
       subject:"accept-namespace", 
       recepient: {id: package.sender.id }, 
       module: package.module, 
       namespace: myNamespace, 
       info: "response to tab exists message" 
       } 
      ) 
      break; 
      } 
      } 
     break; 
    } 
    } 
) 

Also, wenn das Addon eine Nachricht aus dem Modul „easy_options“ erhält, bedeutet dies, dass easy_options.html Bedürfnisse einige Daten, die in das Dokument geladen werden sollen. Deshalb sende ich eine Nachricht mit Namensraum, der die Daten enthält.

Jetzt sind die Addons Seite easy_options.js (wieder, der zweite Teil ist wichtig, wo chrome.runtime.onMessage Hörer hinzugefügt wird):

chrome.tabs.query(
{ active: true, currentWindow: true}, 
    function(tabs) { 
    browser.runtime.sendMessage(
     { message:"initiate-page", 
     subject: "html-add-listeners", 
     module: "easy_options", 
     sender:{id:tabs[0].id} 
     } 
    ) 
    } 
); 

chrome.runtime.onMessage.addListener( 
    function(package, sender 
    ){ 
    switch (package.message){ 
     case "initiate-page-response":  
     if (package.subject == "accept-namespace") 
      { 
      switch(package.module){ 
      case "easy_options": 
       document.addEventListener('DOMContentLoaded', myNamespace.easy.restore); 
       document.getElementById("easy_form_save").addEventListener("submit", myNamespace.easy.save); 
       document.getElementById("easy_form_restore").addEventListener("submit", myNamespace.easy.restore); 
       document.getElementById("easy_form_remove_item").addEventListener("submit", myNamespace.easy.remove_profiles); 
       document.getElementById("easy_form_remove_profiles").addEventListener("submit", myNamespace.easy.remove_profiles); 
       document.getElementById("list").addEventListener("change", myNamespace.easy.restoreDefault); 
      break; 
      } 
      } 
     break; 
    } 
    } 
) 

Was passiert ist: 1. I Nachricht senden (A) in den Hintergrund Hörer und es nimmt die Nachricht 2. Hintergrund Hörer Nachricht (B) 3. Addons Optionen Skript erhält die erste Nachricht (A) in der runtime.OnMessage Hörer (ich diese Nachricht zu verarbeiten, nicht wollen) sendet

Was passieren soll 1. Ich sende mes Sage (A) zu Hintergrund Listener und es akzeptiert die Nachricht 2. Hintergrund Listener sendet Nachricht (B) 3. Addons Optionen Skript empfängt die erste Nachricht (A) in der Runtime.OnMessage Listener (Ich möchte diese Nachricht nicht verarbeiten) 4. Addons Optionen Skript sollte die zweite Nachricht (B) in der Runtime.OnMessage Listener erhalten und ich sollte es verarbeiten

Frage: Warum passiert der vierte Schritt nicht? Warum wird die Nachricht (B-Alias ​​"Initiate-page-response") nicht empfangen?

Vielleicht Chrome-Addon-Programmierer können auch helfen, ich denke, die Dinge sollten ähnlich funktionieren.

+0

Kurze Frage, warum sind Sie auch dies zu tun Messaging-Rundreise? – Xan

Antwort

3

Da es sich um eine Erweiterungsseite und kein Inhaltsskript handelt, wird chrome.tabs.sendMessage es nicht erreichen.

Sie müssen Ihre Nachricht mit chrome.runtime.sendMessage senden, um chrome-extension:// Seiten wie eine Optionsseite zu erreichen.

Wenn Sie nicht über die Sendung Natur runtime.sendMessage mögen, sollten Sie sendResponse Rückruf Argument verwenden, um eine Antwort zurück an den Absender zu übergeben (wahrscheinlich bevorzugt) oder eine langlebige Port mit runtime.connect etablieren.

+0

Vielen Dank – user1141649

+0

sollte sendResponse von runtime.onMessage empfangen werden? Ich habe es versucht, erfolgreich gesendet Antwort, aber ich kann immer noch nicht die Nachricht in addons Optionen Seite erhalten. – user1141649

+0

Nein, 'sendResponse' wird von einem Callback empfangen, der an 'runtime.sendMessage' als zweites Argument übergeben wird.Beachten Sie, dass Sie 'true' vom' onMessage'-Handler zurückgeben müssen, wenn Ihr Aufruf von 'sendResponse' asynchron ist. – Xan

1

Dank Xan Erklärung, habe ich gefunden, das funktioniert wie Charme

Hintergrund Skript:

chrome.runtime.onMessage.addListener( 
    function(package, sender, sendResponse 
    ){ 
    switch (package.message){ 
     case "open": 
     if (package.subject == "tab") 
      { 
      win = myNamespace.tabs[package.module]; 
      result = win ? false : true; 

      if (result) 
      chrome.tabs.create(
       {"url": package.url }, 
       function(tab) {   
       if (chrome.extension.lastError) 
        console.log(chrome.extension.lastError); 
       else 
        myNamespace.tabs[package.module] = tab.id; 
       chrome.tabs.onRemoved.addListener(
        function(tabId, removeInfo)      
        { 
        for (var k in myNamespace.tabs) 
         { 
         if (tabId === myNamespace.tabs[k]) 
         { 
         myNamespace.tabs[k] = null; 
         break; 
         } 
         } 
        } 
       ); 
       } 
      ); 
      } 
     break; 
     case "initiate-page":  
     if (package.subject == "html-add-listeners") 
      { 
      switch(package.module){ 
      case "easy_options": 
      case "advanced_options": 
      case "images_options":    
      sendResponse(
       { message:"initiate-page-response", 
       subject:"accept-namespace", 
       recepient: {id: package.sender.id }, 
       module: package.module, 
       namespace: myNamespace, 
       info: "response to initiate-page message" 
       } 
      ) 
      break; 
      } 
      } 
     break; 
    } 
    } 
) 

Option page script Addon:

chrome.tabs.query(
{ active: true, currentWindow: true}, 
    function(tabs) { 
    browser.runtime.sendMessage(
     { message:"initiate-page", 
     subject: "html-add-listeners", 
     module: "easy_options", 
     sender:{id:tabs[0].id} 
     }, 
     function response(message){ 
     console.log("RESPONSE:"); 
     console.log(message); 
     return true; 
     } 
    ) 
    } 
); 
+1

Diese letzte "Rückkehr wahr" ist überflüssig; Es wird nur in 'onMessage' benötigt und nur wenn 'sendMessage()' asynchron aufgerufen wird. – Xan