2

我正在開發一個谷歌插件/擴展,我遇到了一個問題,我只能推測其原因。在我的background.js後臺腳本中,我試圖將圖像數據發送到我的content.js內容腳本。消息沒有到達首頁加載 - 谷歌瀏覽器消息從後臺傳遞到內容腳本

當我第一次在新選項卡中加載頁面時,我只收到「響應已發送!」,但沒有收到「響應」。然後我用f5鍵刷新,這次我也收到了等待回覆的消息。

有沒有可能我的background.js根本不在內存中呢?如果是的話,我該如何解決這個問題?當我在chrome:// extensions /下重新加載我的插件並重新加載已存在的選項卡時,也會發生這種情況。

background.js

chrome.extension.onMessage.addListener(
function(msg, sender, sendResponse) { 
    if((msg.action && (msg.action == "getPixels")) && msg.imgPath) 
    { 
     var canvas = document.createElement("canvas"); 
     canvas.style.border = "none"; 
     var img = new Image(); 
     img.src = msg.imgPath; 
     var thewaitx = function() 
     { 
      if(img.complete && (img.width + img.height) > 0) 
      { 
       canvas.width = img.width; 
       canvas.height = img.height; 
       canvas.getContext("2d").drawImage(img, 0, 0); 
       data = canvas.getContext("2d").getImageData(0, 0, img.width, img.height).data 

       sendResponse({value: data}); 
       alert("response sent!"); 
      } 
      else {setTimeout(thewaitx, 2000);} 
     }; 
     thewaitx(); 

     } 
    } 
); 

content.js

function findDataBySignature() 
{ 
    img = document.getElementsByClassName("someid")[0].getElementsByTagName("img")[0]; 
    chrome.extension.sendMessage({action: "getPixels", imgPath:img.src}, function(response) 
    { 
     alert("response received"); 
     data = response.value; 
     //blahblah 
    } 
} 
+0

這就是我發現的所有答案的問題。我正在請求我的內容腳本中的數據(不是後臺腳本!)。內容腳本運行,並在某些時候它說,嘿,你哥們,後臺腳本,這裏是網址,發送給我的圖像數據。後臺腳本獲取消息併發送答案,但答案永遠不會返回。我得到「回覆發送!」的事實是內容腳本已經運行的證據,因爲它是唯一可以觸發該呼叫的人。嗯......現在,當我想到這個時,必須加載後臺腳本,因爲我得到了「響應發送!」。奇怪的。 – evolution 2014-09-19 00:26:20

+0

我認爲它與閒置的舊內容腳本無關。我知道新代碼只能在新選項卡中執行。它通常是我正在更新的內容腳本。但這正是我所知道的。我重新加載擴展,然後我重新加載或打開一個新的選項卡。或者我誤解了一些東西? – evolution 2014-09-19 00:32:55

+0

啊!那就是錯誤的問題。但是,再次回答。片刻.. – Xan 2014-09-19 06:02:31

回答

1

對不起,我在第一次連接到錯誤的問題。

在你的代碼中,你正在請求一個圖像,並且根據它是否已經加載,你要麼正在做一些事情,要麼使用setTimout等待。

您的代碼第二次工作,因爲圖像已經加載;第一次不是,並且收聽者終止而不調用sendResponsesetTimeout是異步的)。

谷歌documentation提到,需要特別關注採取讓Chrome瀏覽器現在你要打電話sendResponse異步(而不是簡單地無應答):

此功能失效時,事件偵聽器返回,除非你從事件​​監聽器返回true,表明你希望異步發送響應(這將使消息通道保持開放狀態,直到調用sendResponse)。

因此,要使其工作,你從那裏你不會立即撥打sendResponse分支需要return true;


這麼說,我對你的代碼進行評論:你不應該使用setTimeout等待圖像加載。使用基於事件的方法:

var img = new Image(); 
img.onload = function() { 
    canvas.width = img.width; 
    canvas.height = img.height; 
    canvas.getContext("2d").drawImage(img, 0, 0); 
    data = canvas.getContext("2d").getImageData(0, 0, img.width, img.height).data 

    sendResponse({value: data}); 
    alert("response sent!"); 
}; 
img.src = msg.imgPath; 

// Check if image is already loaded (required if from cache) 
if(img.complete || img.readyState === 4) { img.onload(); } 
else { 
    return true; // For asynchronous sendResponse() call 
} 
+0

謝謝!有效!由於我在這裏是新手,我還沒有投票,但只要我得到15,我會:) – evolution 2014-09-19 19:29:10

+0

如果它的工作,你可以(也應該)接受答案(分數下的複選標記) – Xan 2014-09-19 19:35:23

+0

是的,我之前使用過,但是我遇到了你提到的那些緩存問題。瞭解readystate屬性是很好的。我的代碼中有更多這樣的池。也許我現在要消除這種醜陋。 – evolution 2014-09-19 19:42:15

相關問題