内容和背景之间传递的Chrome扩展程序消息无效

时间:2015-01-07 16:16:28

标签: javascript google-chrome google-chrome-extension

我正在开发一个chrome扩展,这里是主要文件:

background.js

getPageDimension = function (){
    chrome.tabs.getSelected(null, function(tab) {
        chrome.tabs.sendMessage(tab.id, { message: "DIMENSION" }, function(response){
            if (response != null) {
                console.log(response.x);
                console.log(response.y);
                console.log(response.w);
                console.log(response.h);
            }else{
                console.log('Response is null');
            }
        });
    }); 
};

content.js

chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {        
    if (msg.message && (msg.message == "DIMENSION")) {                          
        var dimension = getPageDiemension(document.documentElement);        
        console.log(dimension.x);
        console.log(dimension.y);
        console.log(dimension.w);
        console.log(dimension.h);
        sendResponse({x: dimension.x, y: dimension.y,w: dimension.w,h: dimension.h});       
    }
});

getPageDiemension = function(currentDom){
    var dimension = new Object();
    dimension.x = 0;
    dimension.y = 0;
    dimension.w = currentDom.scrollWidth;
    dimension.h = currentDom.scrollHeight;
    return dimension;
}

所以我的目标是在当前活动选项卡中加载页面的完整高度和宽度。当我调试我的内容脚本时,我在 background.js 中得到了正确的响应,但如果在没有调试的情况下运行脚本,我会收到undefined响应我的background.js

以下是我cotent.js文件中manifest.json的声明:

"content_scripts": [{
    "all_frames": true,
    "matches": [
        "http://*/*", "https://*/*"
    ],
        "js": ["content.js"]
}],

请帮助我,我哪里错了?如果您需要任何进一步的数据,请与我们联系。

1 个答案:

答案 0 :(得分:9)

问题

你的代码中存在两个小问题,我发现它们是在一个诡计之后发现的,因为它看起来非常有效(当它完全没有时)。

  1. 您正在使用已弃用的chrome.tabs.getSelected(...)方法,您应该避免使用该方法。请改用chrome.tabs.query({active: true, highlighted: true}, ...)
  2. chrome.runtime.onMessage侦听器中,在内容脚本中,您在发送响应之前正在进行一些计算:这会使消息通道关闭,然后才能发送响应,并将导致{{ 1}}回复。

    引自the official documentation

      

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

  3. 解决方案

    现在您已经知道问题所在,您可以轻松地将旧版sendResponse替换为tabs.getSelected(),并在tabs.query()事件的处理程序中添加return true;语句在您的内容脚本中。解决方案如下,我也稍微减轻了代码。

    您的runtime.onMessage

    background.js

    您的getPageDimension = function (){ chrome.tabs.query({active: true, highlighted: true}, function(tabs) { chrome.tabs.sendMessage(tabs[0].id, { message: "DIMENSION" }, function(response){ if (response !== null) console.log('Response:', response); else console.log('Response is null'); }); }); };

    content.js

    工作示例

    您可以找到我为测试 HERE 而制作的工作示例。

    文档链接

    为了清楚起见,我为您留下了一些关于此扩展中涉及的API的文档链接,您可能会觉得有用: