开发者问题收集

Chrome 扩展程序:sendMessage 不起作用

2014-04-16
6081

我已经阅读过 Google 关于“消息传递”的文档几次,并且可能已经查看了 10 多个具有相同问题的其他问题,并且已经尝试了他们的大多数“解决方案”以及下面所提供的几种变体......这是黑魔法,对吧?不管怎样,它都在这里。

清单文件:

{
    "manifest_version" : 2,
    "name" : "Message Test",
    "version" : "1.0",

    "browser_action": { 
        "default_popup": "popup.html"
    },

    "background": {
        "scripts": ["background.js"]
    },

    "content_scripts": [
        {
        "matches" : ["<all_urls>"],
        "js": ["message-test.js"]
        }
    ]    
}

我知道扩展不应该使用内联 JS,但是我保留这个,这样原来的问题就可以保持原样,因为我仍然无法从后台页面发送消息,当我从弹出窗口切换到后台时,我从 manifest.json 中删除了相应的行

popup.html 文件:

<html>
  <head>
    <script>
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
      chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello", theMessage: "Why isn\'t this working?"}, function(response) {
        console.log(response.farewell);
      });
    });
    </script>
  </head>
<body>
</body>
</html>

background.js 文件:

chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
  chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello", theMessage: "Why isn\'t this working?"}, function(response) {
    console.log(response.farewell);
  });
});

message-test.js 文件:

var Mymessage;
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
    if (message.greeting == "hello"){
        Mymessage = message.theMessage;
        alert(Mymessage);
    }
    else{
        sendResponse({});
    }
});

我收到未定义的警报……

我也试图在按下弹出窗口中的按钮并在指定的 url 上打开窗口后执行此操作,但那是以后的问题。按钮和窗口的其他文件可以在这里找到,除了用 addEventListener("click".... 包装的 background.js 内容: http://pastebin.com/KhqxLx5y AND http://pastebin.com/JaGcp6tj

3个回答

您的代码中存在几个问题。

Chrome 不允许在扩展程序中使用内联脚本。您必须将 popup.html 分为脚本 + HTML:

// popup.html
<html>
<body>
<script type="text/javascript" src="popup.js"></script>
</body>
</html>

// popup.js
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
    var tab = tabs[0];  // do not forget to declare "tab" variable
    chrome.tabs.sendMessage(tab.id, {
        greeting: "Can you hear me?"
    }, function(response){});
});
KAdot
2014-04-17

仔细阅读 这个答案 可能会对您有所帮助。那里的每一点都适用于您的问题。

您的问题在于您的主脚本何时执行,以及您的内容脚本何时执行。您需要确保在向内容脚本发送消息之前,内容脚本正在监听,在最坏的情况下,以编程方式注入消息。

要使其在弹出窗口中工作,请按照 KAdot 的答案 操作。

Xan
2014-05-28

以下是使用后台脚本的解决方案:

manifest.json

{
    "manifest_version" : 2,
    "name" : "Message Test",
    "version" : "1.0",

    "background":{
        "scripts":["popup.js"]
    },

    "content_scripts": [
        {
        "matches" : ["<all_urls>"],
        "js": ["message-test.js"]
        }
    ]
}

message-test.js

var port = chrome.runtime.connect();
port.onMessage.addListener(function(message, sender, sendResponse) {
    if (message.greeting == "Can you hear me?"){
        alert("Test");
    }
    else{
        sendResponse({});
    }
});

popup.js

chrome.runtime.onConnect.addListener( function ( port ) {
port.postMessage({
        greeting: "Can you hear me?"
    });
});

一些解释:首先,我们从内容脚本连接到后台脚本,然后后台脚本将消息发送到内容脚本。

更新

我根据 @Xan 的评论改进了答案。但想法是一样的,首先你应该让你的后台脚本知道内容脚本的存在。

dIsoVi
2014-05-27