问题描述
看起来像允许网站与扩展进行通信的外部可连接功能仍然在开发通道中,但尚不稳定。有没有其他方法可以让特定网站与我的扩展程序进行通信,而我是否等待此功能稳定? Chrome扩展开发人员传统上如何做到这一点?解决方案
看起来像允许网站与扩展进行通信的外部可连接功能仍然在开发通道中,但尚不稳定。有没有其他方法可以让特定网站与我的扩展程序进行通信,而我是否等待此功能稳定? Chrome扩展开发人员传统上如何做到这一点?解决方案
感谢Rob W将我指向HTML5消息传递的方向。为了其他Chrome扩展开发人员的利益,我正在写关于我试图解决的一般问题以及最终解决方案。
我正在制作一个Chrome扩展,可以通过弹出式播放器控制选项卡上的音乐播放。当用户点击弹出式播放器上的播放/暂停/等时,扩展应该能够将该消息传达给网页并获取响应,说明动作是否已完成。
我的第一种方法是将内容脚本注入音乐播放器页面。但问题是,内容脚本在沙箱中运行,无法在页面上访问原生JavaScript。因此,内容脚本本身是无用的,因为虽然它可以从扩展中接收命令,但它不会影响网页本身的任何更改。
有一件事情对我有利,因为播放音乐的网站属于我,所以我可以把我想要的任何JavaScript都放到服务器上。这正是我使用我的优势:我创建了另一个JavaScript文件,该文件驻留在网站上,并通过页面的窗口对象(即 HTML5消息传递)与上述内容脚本进行通信。这只适用于因为内容脚本和JavaScript文件都存在于同一个网页并且可以共享页面的窗口对象。感谢Rob W为我指出了这一能力。这里是一个例子,说明页面上的JavaScript文件如何通过窗口对象启动与内容脚本的连接:
content_script.js(通过扩展插入到xyz中。
$ b $ pre $ 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(从网页接收到连接请求);
窗口.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(建立连接);
break;
}
}
}
},假);
我检查密钥只是为了确保消息来自我期望的地方。 / p>
就是这样!如果有什么不清楚的地方,或者您有任何问题,请随时跟进!
It seems like the externally_connectable feature that allows a website to communicate with an extension is still in the dev channel and not yet stable. Are there any other ways to allow a specific website to communicate with my extension, while I wait for this feature to become stable? How have chrome extension developers traditionally done it?
Thanks Rob W for pointing me in the direction of HTML5 messaging. For the benefit of other chrome extension developers, I'm writing about the general problem I was trying to solve and the solution that worked in the end.
I am making a chrome extension that can control music playback on a tab via a popup player. When a user clicks on play/pause/etc on the popup player, the extension should be able to convey that message to the webpage and get back a response stating whether the action was accomplished.
My first approach was to inject a content script into the music player page. The problem is, though, that content scripts operate in a "sandbox" and cannot access native javascript on the page. Therefore, the content script was pretty useless (on its own), because while it could receive commands from the extension, it could not effect any change on the webpage itself.
One thing that worked in my favor was that the website where the music was playing belongs to me, so I could put whatever javascript I wanted there and have it be served from the server. That's exactly what I used to my advantage: I created another javascript file that would reside on the website and communicate with the content script mentioned above, via the window object of the page (i.e. HTML5 messaging). This only works because the content script and the javascript file both exist in the same webpage and can share the window object of the page. Thanks Rob W for pointing me to this capability. Here is an example of how the javascript file on the page can initiate a connection with the content script via the window object:
content_script.js (injected by extension into 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 (resides on server and served along with 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);
I check the secret key just to make sure that the message originates from where I expect it to.
That's it! If anything is unclear, or if you have any questions, feel free to follow up!
这篇关于铬扩展 - 替代外部可连接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!