消息未在首页加载时到达 - Google Chrome消息从后台传递到内容脚本

时间:2014-09-18 23:03:48

标签: javascript google-chrome google-chrome-extension background message-passing

我正在开发一个谷歌插件/扩展程序,我遇到了一个问题,我只能推测它的原因。在我的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
    }
}

1 个答案:

答案 0 :(得分:1)

很抱歉首先链接到错误的问题。

在您的代码中,您正在申请图片,并且根据图片是否已经加载,您要么对其执行操作,要么使用setTimout等待。

您的代码第二次运行,因为图像已经加载;第一次不是,并且监听器终止而不调用sendResponsesetTimeout是异步的)。

Google documentation提到需要特别注意让Chrome现在以异步方式调用sendResponse(而不是简单地没有回复):

  

当事件侦听器返回时,此函数变为无效,除非您从事件侦听器返回true以指示您希望异步发送响应(这将使消息通道保持打开到另一端,直到调用sendResponse )。

因此,为了使其有效,您需要return true;来自您不会立即致电sendResponse的分支机构。


那就是说,我必须对您的代码发表评论:您不应该使用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
}