似乎允许网站与扩展程序通信的 externally_connectable 功能仍处于开发通道中,并且还不稳定。在我等待此功能稳定的同时,还有其他方法可以让特定网站与我的扩展程序通信吗?chrome 扩展开发人员传统上是如何做到的?
2 回答
感谢 Rob W 为我指明了 HTML5 消息传递的方向。为了其他 chrome 扩展开发人员的利益,我正在写关于我试图解决的一般问题以及最终有效的解决方案。
我正在制作一个 chrome 扩展,可以通过弹出播放器控制标签上的音乐播放。当用户在弹出播放器上单击播放/暂停/等时,扩展程序应该能够将该消息传达给网页并返回说明操作是否完成的响应。
我的第一种方法是将内容脚本注入音乐播放器页面。但问题是,内容脚本在“沙箱”中运行,无法访问页面上的本机 JavaScript。因此,内容脚本(就其本身而言)毫无用处,因为虽然它可以从扩展程序接收命令,但它无法对网页本身进行任何更改。
对我有利的一件事是播放音乐的网站属于我,所以我可以将任何我想要的 javascript 放在那里,并从服务器提供它。这正是我使用的优势:我创建了另一个 javascript 文件,该文件将驻留在网站上,并通过页面的 window 对象(即HTML5 消息传递)与上述内容脚本进行通信。这只是因为内容脚本和javascript文件都存在于同一个网页中,并且可以共享页面的窗口对象。感谢 Rob W 向我指出了这种能力。以下是页面上的 javascript 文件如何通过 window 对象启动与内容脚本的连接的示例:
content_script.js(通过扩展注入 xyz.com):
window.addEventListener("message", function(event) {
if(event.data.secret_key &&
(event.data.secret_key === "my_secret_key") &&
event.data.source === "page"){
if(event.data.type){
switch(event.data.type) {
case 'init':
console.log("received connection request from page");
window.postMessage({source: "content_script", type: 'init',
secret_key: "my_secret_key"}, "*");
break;
}
}
}
}, false);
onpage.js(驻留在服务器上并与 xyz.com 一起提供):
window.postMessage({source: "page", type: 'init',
secret_key: "my_secret_key"}, "*");
window.addEventListener("message", function(event) {
if(event.data.secret_key &&
(event.data.secret_key === "my_secret_key") &&
event.data.source === "content_script"){
if(event.data.type){
switch(event.data.type) {
case 'init':
console.log("connection established");
break;
}
}
}
}, false);
我检查密钥只是为了确保消息来自我期望的地方。
而已!如果有任何不清楚的地方,或者您有任何疑问,请随时跟进!
您可以让扩展程序在网页旁边注入内容脚本,并使用它在网站和扩展程序的背景页面之间来回传递消息。
不过,这很乏味,而且可外部连接要好得多。