【发布时间】:2012-07-10 23:50:27
【问题描述】:
我想从随机网页的控制台向我的 chrome 扩展程序发送消息。 chrome.extension.sendMessage 似乎不起作用。
【问题讨论】:
标签: google-chrome-extension google-chrome-devtools
我想从随机网页的控制台向我的 chrome 扩展程序发送消息。 chrome.extension.sendMessage 似乎不起作用。
【问题讨论】:
标签: google-chrome-extension google-chrome-devtools
根据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。
它看起来很复杂,也有点复杂,但是所有这些大杂烩都是非常安全的。
【讨论】:
windows.postMessage(...) 所以显然你甚至不需要自定义 myCustomEventDiv,因为它是......
这里引用最新的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); });
【讨论】:
chrome.runtime.onMessageExternal.addListener()收听事件
详细说明,一个更具体的示例:chrome.runtime.sendMessage(...) 样式的一个问题是您必须将您所在的页面指定为 externally_connectable ,它不采用像“https:// 这样的全局通配符/”。所以如果你想要那种能力,你必须使用postMessagestyle通信。将消息从窗口捕获到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);
【讨论】:
您可以使用页面开发者 JS 控制台底部的 <page context> 菜单切换到内容脚本的 JS 执行上下文,然后像在内容脚本中一样使用 chrome.runtime.sendMessage 和其他 chrome.* API .
【讨论】:
chrome://extensions) 并单击 Inspect views: background page 链接来访问扩展上下文控制台,因此缺少上下文切换菜单真的不是什么大问题。
<top frame> 下看到它。
<top frame>,即使页面脚本能够毫无问题地与扩展程序通信。但由于我可以使用扩展页面中的背景页面链接,这只是一个表面问题。
window.foo = 'bar'; 放在内容脚本中,您将不会在后台页面检查控制台中看到它。 afaics 只能通过 jaredjacobs 在此处指出的下拉列表(现在位于“顶部”下方)查看。
除了@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;
});
【讨论】: