5

Ich kann keine Antwort von meinem Inhaltsskript erhalten, um in meinem popup.html zu erscheinen. Wenn dieser Code ausgeführt wird und auf die Schaltfläche Suchen geklickt wird, "Hallo von Antwort!" druckt, aber die variable Antwort wird als undefiniert gedruckt. Das ultimative Ziel ist es, das DOM des aktuellen Tabs in meine Skriptdatei zu bekommen, damit ich es analysieren kann. Ich verwende eine einmalige Nachricht an ein Inhaltsskript, um das DOM zu erhalten, aber es wird nicht zurückgegeben und wird als undefiniert angezeigt. Ich suche nach möglicher Hilfe. Vielen Dank.Nicht definierte Antwort vom Inhaltsskript in der Chrome-Erweiterung

popup.html:

<!DOCTYPE html> 
<html> 
    <body> 
     <head> 
     <script src="script.js"></script> 
     </head> 

     <form > 
      Find: <input id="find" type="text"> </input> 
     </form> 
     <button id="find_button"> Find </button> 
    </body> 
</html> 

manifest.json:

{ 
    "name": "Enhanced Find", 
    "version": "1.0", 
    "manifest_version": 2, 
    "description": "Ctrl+F, but better", 
    "browser_action": { 
     "default_icon": "icon.png", 
     "default_popup": "popup.html" 
    }, 
    "permissions": [ 
     "tabs", 
     "*://*/*" 
    ], 

    "background":{ 
     "scripts": ["script.js"], 
     "persistent": true 
    }, 

    "content_scripts":[ 
     { 
      "matches": ["http://*/*", "https://*/*"], 
      "js": ["content_script.js"], 
      "run_at": "document_end" 
     } 
    ] 
} 

script.js:

var bkg = chrome.extension.getBackgroundPage(); 


function eventHandler(){ 
    var input = document.getElementById("find"); 
    var text = input.value; 
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs){ 
     var tab = tabs[0]; 
     var url = tab.url; 
     chrome.tabs.sendMessage(tab.id, {method: "getDocuments"}, function(response){ 
      bkg.console.log("Hello from response!"); 
      bkg.console.log(response); 
     }); 

    }); 
} 

content_script.js:

var bkg = chrome.extension.getBackgroundPage(); 

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){ 
    if(request.method == "getDOM"){ 
     sendResponse({data : bkg.document}); 
    }else{ 
     sendResponse({}); 
    } 
}); 
+0

Einige Bemerkungen für den Anfang: 1. Sie senden die Nachricht '{ Methode: "getDocuments"} ', aber horche nach' {method: "getDOM"} '. 2. Auch wenn die Nachrichten übereinstimmen würden, würden Sie das Dokument Ihrer Hintergrundseite zurücksenden. 3. Sie führen zwei separate Instanzen von 'script.js' aus: eine auf Ihrer Hintergrundseite und eine in Ihrem Popup. 4. Sie scheinen einige Begriffe (wie Hintergrundseite, Popup, Inhaltsskript) gerade zu erhalten. 5. Sie verwenden eine persistente Hintergrundseite, wenn eine Ereignisseite (nicht persistente Hintergrundseite) gleichermaßen effektiv, aber wesentlich "ressourcenschonender" wäre. – gkalpak

+0

(Das heißt, ja, ich werde versuchen, bald eine tatsächliche Antwort zu finden :)) – gkalpak

+0

Haben Sie meine vorgeschlagene Lösung unten versucht? Hat es für dich funktioniert? – gkalpak

Antwort

15

Es gibt einige Probleme mit Ihrem Code (siehe meinen obigen Kommentar). erste


Einige Vorschläge/Überlegungen:

  • Injizieren Sie nicht Ihre Inhalte Skript in alle Webseiten. Inject programmatically und nur wenn der Benutzer suchen möchte.

  • Es könnte eine bessere Idee sein, das "Suchen" direkt im Inhaltsskript durchzuführen, wo Sie direkten Zugriff auf das DOM haben und es manipulieren können (z. B. Suchergebnisse hervorheben usw.). Sie müssen möglicherweise Ihre Berechtigungen anpassen, wenn Sie für diesen Ansatz gehen, aber immer versuchen, sie auf ein Minimum zu halten (z. B. nicht tabs verwenden, wo activeTab würde ausreichen, usw.).

  • Denken Sie daran, dass alle Popups, die im Popup-Kontext ausgeführt werden, abgebrochen werden, sobald das Popup geschlossen bzw. ausgeblendet ist (z. B. wenn ein Tab den Fokus erhält).

  • Wenn Sie eine Art von Persistenz (auch vorübergehend) wollen, z. Wenn Sie sich die letzten Ergebnisse oder den letzten Suchbegriff merken, können Sie etwas wie chrome.storage oder localStorage verwenden.


Schließlich Beispielcode aus meiner Demo-Version Ihrer Erweiterung:

Erweiterung Dateien Organisation:

  extension-root-directory/ 
      | 
      |_____fg/ 
      |  |_____content.js 
      | 
      |_____popup/ 
      |  |_____popup.html 
      |  |_____popup.js 
      | 
      |_____manifest.json 

manifest.json:

{ 
    "manifest_version": 2, 
    "name": "Test Extension", 
    "version": "0.0", 
    "offline_enabled": true, 

    "content_scripts": [ 
     { 
      "matches": [ 
       "http://*/*", 
       "https://*/*" 
      ], 
      "js":  ["fg/content.js"], 
      "run_at": "document_end", 
     } 
    ], 

    "browser_action": { 
     "default_title": "Test Extension", 
     "default_popup": "popup/popup.html" 
    } 
} 

Inhalt.js:

// Listen for message... 
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { 
    // If the request asks for the DOM content... 
    if (request.method && (request.method === "getDOM")) { 
     // ...send back the content of the <html> element 
     // (Note: You can't send back the current '#document', 
     // because it is recognised as a circular object and 
     // cannot be converted to a JSON string.) 
     var html = document.all[0]; 
     sendResponse({ "htmlContent": html.innerHTML }); 
    } 
}); 

popup.html:

<!DOCTYPE html> 
<html> 
    <head> 
     <script type="text/javascript" src="popup.js"></script> 
    </head> 
    <body> 
     Search: 
     <input type="text" id="search" /> 
     <input type="button" id="searchBtn" value=" Find " 
       style="width:100%;" /> 
    </body> 
</html> 

popup.js:

window.addEventListener("DOMContentLoaded", function() { 
    var inp = document.getElementById("search"); 
    var btn = document.getElementById("searchBtn"); 

    btn.addEventListener("click", function() { 
     var searchTerm = inp.value; 
     if (!inp.value) { 
      alert("Please, enter a term to search for !"); 
     } else { 
      // Get the active tab 
      chrome.tabs.query({ 
       active: true, 
       currentWindow: true 
      }, function(tabs) { 
       // If there is an active tab... 
       if (tabs.length > 0) { 
        // ...send a message requesting the DOM... 
        chrome.tabs.sendMessage(tabs[0].id, { 
         method: "getDOM" 
        }, function(response) { 
         if (chrome.runtime.lastError) { 
          // An error occurred :(
          console.log("ERROR: ", chrome.runtime.lastError); 
         } else { 
          // Do something useful with the HTML content 
          console.log([ 
           "<html>", 
           response.htmlContent, 
           "</html>" 
          ].join("\n")); 
         } 
        }); 
       } 
      }); 
     } 
    }); 
}); 
+0

So viele gute Informationen in dieser Antwort, ich wünschte, ich könnte zweimal upvote. Eine große Ressource ist extensionzr.com, die ein korrekt entworfenes Erweiterungs-Framework erstellen wird. – TrophyGeek

+0

Hey, was ist der Downvote für ??? – gkalpak

+0

Ummm ... ich? Ich habe gestimmt. – TrophyGeek