从网页向chrome扩展程序发送消息

dil*_*023 47 google-chrome-extension google-chrome-devtools

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

Sil*_*ian 58

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

这是一个例子:

您网站的page.html

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

内容脚本:(注入使用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);
    }
});
Run Code Online (Sandbox Code Playgroud)

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

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

它看起来很复杂,有点复杂,但所有这些都非常安全.

  • @kzahel 内容脚本在自己的上下文中运行,因此它与网页上下文隔离。内容脚本可以访问 DOM(HTML 元素),基本上,如果您想在上下文之间传递数据,您可以附加侦听器,您可以通过事件来做到这一点。请注意,有 3 种不同的上下文:扩展、自定义脚本和网页脚本。 (2认同)
  • 第一个链接提到使用`windows.postMessage(...)`,因此显然您甚至不需要自定义myCustomEventDiv,因为... (2认同)

hew*_*ens 47

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

从网页发送消息

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

"externally_connectable": {
  "matches": ["*://*.example.com/*"]
}
Run Code Online (Sandbox Code Playgroud)

这会将消息传递API公开给任何与您指定的URL模式匹配的页面.URL模式必须至少包含一个二级域 - 即禁止使用".",". com",".co.uk"和" .appspot.com"以及<all_urls> 等主机名模式.在Web页面中,使用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);
  });
Run Code Online (Sandbox Code Playgroud)

从您的应用程序或扩展程序,您可以通过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);
  });
Run Code Online (Sandbox Code Playgroud)

  • 可怕的文档,真的 (4认同)
  • 使用`chrome.runtime.onMessageExternal.addListener()`收听事件 (3认同)
  • @user1311069 扩展 ID 生成机制解释如下:http://stackoverflow.com/a/21500707/258772 (2认同)

jar*_*obs 5

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

在此输入图像描述


rog*_*ack 5

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

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

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

例如,你可以将它添加到这样的按钮:

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

然后要在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);
Run Code Online (Sandbox Code Playgroud)