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

标签 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
    }
}

最佳答案

抱歉,一开始链接到错误的问题。

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

您的代码第二次运行是因为图像已经加载;第一次不是,监听器没有调用 sendResponse 就终止了(setTimeout 是异步的)。

谷歌 documentation提到需要特别注意让 Chrome 现在您要异步调用 sendResponse(而不是简单地没有响应):

This function becomes invalid when the event listener returns, unless you return true from the event listener to indicate you wish to send a response asynchronously (this will keep the message channel open to the other end until sendResponse is called).

因此,要使其正常工作,您需要从不会立即调用 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
}

关于javascript - 消息未在第一页加载时到达 - Google Chrome 消息从后台传递到内容脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25923835/

相关文章:

javascript - 导航到页面的某个部分

javascript - 无法让 select2 使用 json 文件

ruby-on-rails - Highcharts 超过了 chrome 中的容器

javascript - 使用 chrome api 在 javascript 中调用嵌套回调函数

javascript - DeselectAll 不适用于 Bootstrap-select

javascript - 如何从对象构建查询字符串?

javascript - JS : window. 滚动(x,y)指向另一个框架在 Chrome 中不起作用

html - 谷歌浏览器 - 放大/缩小时呈现差异

javascript - Chrome 扩展保存数据

javascript - chrome.tabs.update() 重定向到 'chrome-extension://invalid/'