从网页向 chrome 扩展发送消息
Posted
技术标签:
【中文标题】从网页向 chrome 扩展发送消息【英文标题】:sending message to chrome extension from a web page 【发布时间】:2012-07-10 23:50:27 【问题描述】:我想从随机网页的控制台向我的 chrome 扩展程序发送消息。 chrome.extension.sendMessage 似乎不起作用。
【问题讨论】:
【参考方案1】:根据the official docs,您应该在发送方使用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
(不是扩展的一部分)向自己发布消息,内容脚本会拦截和检查这些消息。反过来也可以通过类似的方式。
要从内容脚本传递到扩展,您必须使用one of the available message-passing techniques。
它看起来很复杂,也有点复杂,但是所有这些大杂烩都是非常安全的。
【讨论】:
我可以尝试在网站的 html 中插入代码以通过“chrome.tabs.executeScript()”命令调度事件吗?我厌倦了它,它不工作......它说,“端口错误:无法建立连接:接收端不存在: 谢谢。我想知道如何比 window.postMessage 更安全地执行此操作。这肯定会产生更少的副作用,但不幸的是仍然可能被恶意网页篡改。我很期待chrome.runtime.onMessageExternal,这将允许一个更安全(希望)的沟通渠道 @kzahel 内容脚本在它们自己的上下文中运行,因此它与网页上下文隔离。内容脚本可以访问 DOM(HTML 元素),基本上,如果你想在上下文之间传递数据,你可以附加监听器,你可以通过事件来做到这一点。请注意,有 3 种不同的上下文:扩展、自定义脚本和网页脚本。 第一个链接提到使用windows.postMessage(...)
所以显然你甚至不需要自定义 myCustomEventDiv,因为它是......
很高兴在搜索了一个小时后找到了这个。感谢您的写作!【参考方案2】:
这里引用最新的http://developer.chrome.com/extensions/messaging.html,现在支持这种功能要简单得多,方法如下:
从网页发送消息
与跨扩展消息传递类似,您的应用或扩展可以 接收和回复来自常规网页的消息。要使用这个 功能,您必须首先在您的
manifest.json
中指定哪个网站 您想与之交流的网站。例如:"externally_connectable": "matches": ["*://*.example.com/*"]
这会将消息传递 API 公开给与 URL 匹配的任何页面 您指定的模式。 URL 模式必须至少包含一个 二级域 - 即主机名模式,如“”、“.com”、 禁止使用“.co.uk”、“.appspot.com”和 。 在网页中,使用 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); );
【讨论】:
@user1311069 扩展ID生成机制在这里解释:***.com/a/21500707/258772 用chrome.runtime.onMessageExternal.addListener()
收听事件
请注意,从 FF 54 开始,此方法目前在 Firefox 中不起作用。请参阅此以获得可能的解决方案:***.com/questions/44592605/…
无法从未知域的脚本发送消息,因为它必须在 manifest.json 中定义
糟糕的文档,真的【参考方案3】:
详细说明,一个更具体的示例:chrome.runtime.sendMessage(...)
样式的一个问题是您必须将您所在的页面指定为 externally_connectable ,它不采用像“https:// 这样的全局通配符/”。所以如果你想要那种能力,你必须使用postMessage
style通信。将消息从窗口捕获到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);
【讨论】:
【参考方案4】:您可以使用页面开发者 JS 控制台底部的 <page context>
菜单切换到内容脚本的 JS 执行上下文,然后像在内容脚本中一样使用 chrome.runtime.sendMessage
和其他 chrome.*
API .
【讨论】:
如果屏幕截图中显示的执行上下文切换菜单没有出现,可能是什么原因(Chrome v 39.0.2171.95 m,Windows 7)? 仅供参考 - 我可以通过打开扩展页面 (chrome://extensions
) 并单击 Inspect views: background page 链接来访问扩展上下文控制台,因此缺少上下文切换菜单真的不是什么大问题。
在最近的版本中,Chrome 将执行上下文菜单与框架菜单结合在一起。如果您的扩展程序在页面中有内容脚本,您现在应该会在<top frame>
下看到它。
感谢您的提示。不幸的是,当我单击下拉菜单时,我只看到<top frame>
,即使页面脚本能够毫无问题地与扩展程序通信。但由于我可以使用扩展页面中的背景页面链接,这只是一个表面问题。
@mrts 后台脚本!= 内容脚本。这里有 3 个独立的 JS 执行上下文:页面脚本(默认情况下您在控制台中看到的内容)、后台脚本(您在检查后台页面时看到的内容,并且是所有 Chrome 选项卡的通用 [一个实例])和内容脚本,它在 manifest.json 中定义的给定选项卡 + 给定 url 内运行。如果您将window.foo = 'bar';
放在内容脚本中,您将不会在后台页面检查控制台中看到它。 afaics 只能通过 jaredjacobs 在此处指出的下拉列表(现在位于“顶部”下方)查看。【参考方案5】:
除了@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;
);
【讨论】:
以上是关于从网页向 chrome 扩展发送消息的主要内容,如果未能解决你的问题,请参考以下文章
为啥从 WatchKit 扩展向 iOS 发送消息并得到回复如此缓慢?
通过 POST 请求向 Discord 频道发送消息会导致代码 401