5

我無法從我的內容腳本中獲得響應以顯示在我的popup.html中。當此代碼運行並單擊查找按鈕時,「來自響應的問候!」打印,但變量響應打印爲未定義。最終目標是將當前選項卡的DOM放入我的腳本文件中,以便我可以解析它。我使用單個時間消息來訪問內容腳本來獲取DOM,但它沒有被返回並顯示爲未定義。我正在尋找任何可能的幫助。謝謝。來自Chrome擴展中的內容腳本的未定義響應

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

對於初學者一些備註:1。你要發送的消息'{方法:「getDocuments」}',但聽取'{method:「getDOM」}'。即使信息匹配,你也會發回你背景頁面的文件。 3.您正在運行'script.js'的兩個獨立實例:一個在您的背景頁面,另一個在您的彈出窗口中。 4.您似乎需要直接獲取一些術語(如背景頁面,彈出窗口,內容腳本)。 5.當一個事件頁面(非持久背景頁面)同樣有效時,您使用的是持久背景頁面,但顯着更「資源友好」。 – gkalpak

+0

(這就是說,是的,我會盡快想出一個實際的答案:)) – gkalpak

+0

你試過我的建議解決方案下面?它對你有用嗎? – gkalpak

回答

15

你的代碼有很多問題(請參閱我上面的評論)。


一些建議/注意事項第一:

  • 不要注入的內容腳本到所有網頁。 Inject programmatically並且僅當用戶想要搜索時。

  • 在內容腳本中執行「搜索」權利可能是一個好主意,您可以直接訪問DOM並對其進行操作(例如突出顯示搜索結果等)。如果你採用這種方法,你可能需要調整你的權限,但總是儘量保持它們的最低限度(例如,不要使用tabs,其中activeTab就足夠了,等等)。請注意,一旦彈出窗口被關閉/隱藏(例如一個標籤接收焦點),所有在彈出窗口中執行的JS都會中止。

  • 如果你想要某種持久性(甚至是暫時的),例如記住最近的結果或上一個搜索詞,可以使用類似chrome.storagelocalStorage


最後,從您的擴展我的演示版本的示例代碼:

擴展名文件組織:

  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" 
    } 
} 

內容。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

在這個回覆中有很多很好的信息,我希望我能兩次提高。一個很好的資源是extensionizr.com,它將構建一個正確設計的擴展框架。 – TrophyGeek

+0

嘿,什麼是downvote ??? – gkalpak

+0

呃......我?我upvoted。 – TrophyGeek

相關問題