60

我想从随机网页的控制台向我的 chrome 扩展程序发送消息。chrome.extension.sendMessage 似乎不起作用。

4

5 回答 5

76

根据官方文档,您应该在接收者postMessage的发送者和message事件监听器中使用。

这是一个例子:

您网站的 page.html

var data = { type: "FROM_PAGE", text: "Hello from the webpage!" };
window.postMessage(data, "*");

内容脚本:(使用注入chrome.tabs.executeScript(tabid, {code:...

window.addEventListener("message", function(event) {
    // We only accept messages from ourselves
    if (event.source != window)
        return;

    if (event.data.type && (event.data.type == "FROM_PAGE")) {
        console.log("Content script received message: " + event.data.text);
    }
});

这里page.html(不是扩展的一部分)向自己发布消息,内容脚本会拦截和检查这些消息。通过类似的方式可以反过来。

要从内容脚本传递到扩展,您必须使用一种可用的消息传递技术

它看起来很复杂,而且有点复杂,但是所有这些大话都非常安全。

于 2012-07-11T11:37:06.080 回答
54

这是最新的http://developer.chrome.com/extensions/messaging.html的引用,现在支持这种功能要简单得多,方法如下:

从网页发送消息

与跨扩展消息传递类似,您的应用或扩展可以接收和响应来自常规网页的消息。要使用此功能,您必须首先在您的manifest.json网站中指定您要与之通信的网站。例如:

"externally_connectable": {
  "matches": ["*://*.example.com/*"]
}

这会将消息传递 API 公开给与您指定的 URL 模式匹配的任何页面。URL 模式必须至少包含一个二级域 - 即,禁止使用“ ”、“. com”、“. co.uk”、“ .appspot.com”和 <all_urls> 等主机名模式。在网页中,使用 runtime.sendMessage 或 runtime.connect API 将消息发送到特定应用程序或扩展程序。例如:

// The ID of the extension we want to talk to.
var editorExtensionId = "abcdefghijklmnoabcdefhijklmnoabc";

// Make a simple request:
chrome.runtime.sendMessage(editorExtensionId, {openUrlInEditor: url},
  function(response) {
    if (!response.success)
      handleError(url);
  });

在您的应用程序或扩展程序中,您可以通过 runtime.onMessageExternal 或 runtime.onConnectExternal API 收听来自网页的消息,类似于跨扩展程序消息传递。只有网页可以发起连接。这是一个例子:

chrome.runtime.onMessageExternal.addListener(
  function(request, sender, sendResponse) {
    if (sender.url == blacklistedWebsite)
      return;  // don't allow this web page access
    if (request.openUrlInEditor)
      openUrl(request.openUrlInEditor);
  });
于 2013-12-21T07:02:16.427 回答
10

因此,详细说明,一个更具体的示例:chrome.runtime.sendMessage(...)样式的一个问题是您必须将您所在的页面指定为 externally_connectable ,它不采用像“https:// / ”这样的全局通配符。所以如果你想要那种能力,你必须使用postMessage 风格交流。将消息从窗口捕获到 中contentscript,然后从 中contentscript,您可以将其发送到其他地方(如果需要,例如发送到background.js等)

因此,在普通网页中,或在您嵌入到普通页面的注入源中,从您的contentscript.js中,发送如下消息:

window.postMessage({ type: "FROM_PAGE_TO_CONTENT_SCRIPT", 
     text: "Hello from the webpage!" }, "*");

例如,您可以将其添加到这样的按钮中:

document.getElementById("theButton").addEventListener("click",
    function() {
       window.postMessage({ type: "FROM_PAGE_TO_CONTENT_SCRIPT", 
                            text: "Hello from the webpage!" }, "*");
}, false);

然后在 contentscript.js 中捕获它并将其“发送”到扩展的其余部分,唯一需要注意的是,您只想“选择”似乎是您关心的消息:

window.addEventListener("message", function(event) {
  // We only accept messages from this window to itself [i.e. not from any iframes]
  if (event.source != window)
    return;

  if (event.data.type && (event.data.type == "FROM_PAGE_TO_CONTENT_SCRIPT")) {        
    chrome.runtime.sendMessage(event.data); // broadcasts it to rest of extension, or could just broadcast event.data.payload...
  } // else ignore messages seemingly not sent to yourself
}, false);
于 2017-01-24T18:33:12.847 回答
5

您可以使用<page context>页面开发人员 JS 控制台底部的菜单切换到内容脚本的 JS 执行上下文,然后像在内容脚本中一样使用chrome.runtime.sendMessage其他chrome.*API。

在此处输入图像描述

于 2013-11-25T23:43:34.833 回答
4

除了@hewigovens,我没有足够的评论点......我正在解释@renatoargh 和@sbichenko 如果从默认网页发送消息 -

1)网页需要在manifest中引用。例如:

"externally_connectable": {
  "matches": ["http://abcde/abcde/main.aspx*"]
}

2)background.js(背景页面)除了调用 onMessageExternal 例如(调用扩展):

var host_name = "com.my_chrome_extension.com";
 chrome.runtime.onMessageExternal.addListener(function(message, sender, sendResponse) {
    chrome.runtime.sendNativeMessage(host_name, {"run":message});
    sendResponse({"success": "success"});
    return true;
});
于 2016-05-15T09:52:47.557 回答