感谢 Rob W 为我指明了 HTML5 消息传递的方向。为了其他 Chrome 扩展开发人员的利益,我正在撰写有关我试图解决的一般问题以及最终有效的解决方案的文章。
我正在制作一个 chrome 扩展,可以通过弹出播放器控制选项卡上的音乐播放。当用户单击弹出播放器上的播放/暂停等时,扩展程序应该能够将该消息传达给网页并返回一个响应,说明该操作是否已完成。
我的第一个方法是将内容脚本注入音乐播放器页面。但问题是,内容脚本在“沙箱”中运行,无法访问页面上的本机 JavaScript。因此,内容脚本(就其本身而言)非常无用,因为虽然它可以从扩展程序接收命令,但它无法对网页本身产生任何更改。
对我有利的一件事是,播放音乐的网站属于我,因此我可以将我想要的任何 JavaScript 放在那里并从服务器提供服务。这正是我所利用的优势:我创建了另一个 javascript 文件,该文件将驻留在网站上,并通过页面的窗口对象(即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);
我检查密钥只是为了确保消息来自我期望的地方。
就是这样!如果还有什么不清楚的地方,或者有什么疑问,欢迎继续关注!