google-chrome-extension - 消息传递不起作用

标签 google-chrome-extension

bacground.js

chrome.tabs.create({url: "http://www.google.com", "active":true}, function(tab) {
console.log(tab.id);// 315
chrome.tabs.sendMessage(tab.id, {greeting: "hello"}, function(response) {
console.log(response.farewell);
});
});

内容脚本.js

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    console.log(sender.tab ?
                "from a content script:" + sender.tab.url :
                "from the extension");
    if (request.greeting == "hello")
      sendResponse({farewell: "goodbye"});
  });
});

日志:

Port: Could not establish connection. Receiving end does not exist. 

如何解决?

最佳答案

发生此错误的原因似乎是,当您的后台脚本发送消息时,内容脚本尚未注入(inject)到页面中。因此,“接收端不存在。”

我假设(因为我没有超过 50 名代表能够对您的问题发表评论并首先澄清这一点,所以如果我错了请纠正我)在您的 manifest.json 文件中指定它通过以下方式:

"content_scripts": [{
    "matches": ["*://xyz.com/*"],
    "js": ["contentscript.js"]
}]

如果这确实是您注入(inject)内容脚本的方式,那么您需要知道内容脚本仅在 DOM 完成渲染后才会注入(inject)。 (在以下链接中搜索“run_at”:http://developer.chrome.com/extensions/content_scripts.html)这意味着当您从后台脚本发送该消息时,内容脚本仍处于“加载中”。

好消息是,您可以通过向 manifest.json 文件中的 content_scripts 参数添加第三个键值对来指定何时加载内容脚本,如下所示:

"content_scripts": [{
    "matches": ["*://xyz.com/*"],
    "js": ["contentscript.js"],
    "run_at": "document_start"
}]

这告诉扩展您想要在构建 DOM 或运行任何其他脚本之前注入(inject) contentscript.js(即尽早)。

如果上述技术仍然给您带来相同的错误,则表明甚至 document_start 还不够早。在这种情况下,我们完全考虑另一种方法。您目前正在尝试做的是将后台脚本连接到内容脚本。当内容脚本已成功注入(inject)页面时,为什么不让内容脚本连接到后台脚本?后台页面始终运行,因此保证能够从内容脚本接收消息,而不会提示“接收端不存在”。以下是您的操作方法:

在background.js中:

chrome.runtime.onConnect.addListener(function(port) {
    console.log("background: received connection request from 
                 content script on port " + port);
    port.onMessage.addListener(function(msg) {
        console.log("background: received message '" + msg.action + "'");
        switch (msg.action) {
            case 'init':
                console.log("background script received init request 
                             from content script");
                port.postMessage({action: msg.action});
                break;
        }
    });
});

在 contentscript.js 中:

var port_to_bg = chrome.runtime.connect({name: "content_to_bg"});
port_to_bg.postMessage({action: 'init'});
port_to_bg.onMessage.addListener(function(msg) {
    switch (msg.action) {
        case 'init':
            console.log("connection established with background page!");
            break;
    }
}

欢迎提出更多问题以求澄清!我很想知道第一种方法是否有效。如果没有,第二种方法肯定会获胜。

关于google-chrome-extension - 消息传递不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18313669/

相关文章:

javascript - Chrome 扩展发布请求不发送数据

javascript - chrome.storage.local 写入 key 的问题

javascript - 使用异步 chrome.cookies.getAll 的结果

javascript - 带有 url + 选定文本的新标签(js,Chrome 扩展)

javascript - 尝试将文件上传到 Google Drive 时不断收到“需要登录”错误

javascript - 在chrome扩展中使用ajax查询

javascript - 如何限制用户在 Chrome 扩展选项中输入 float

google-chrome - Chrome 扩展程序的 activeTab 权限问题

javascript - onclick 或内联脚本在扩展中不起作用

javascript - 如何在Chrome扩展程序中找到带有JavaScript的YouTube不喜欢按钮?