我在Javascript运行时中有一个方法,用于从扩展程序的内容脚本中触发的选项卡。从表面上看,这要求在上下文之间传递消息,但我找不到任何CS到标签消息的文档,只有tab-to-CS或CS-to-background。基本上我想翻转内容脚本引用的Communication with the embedding page部分。
到目前为止,我通过注入一个小的javascript有效负载将一个事件监听器附加到选项卡的window
(这将触发正确类型的消息上的tab方法):
listenerScript = document.createElement('script');
listenerScript.textContent = "window.addEventListener('message',function(ev){console.log('New event: ' + ev);},false);console.log('installed');";
(document.head||document.documentElement).appendChild(listenerScript);
listenerScript.remove();
此侦听器已注册,但我无法弄清楚如何从我的内容脚本中触发它。内容脚本中的window.postMessage()
似乎没有做任何事情,文档只谈到使用chrome.runtime
创建一个端口,用于后台脚本。
如何以最简单的方式将消息从内容脚本传递到选项卡?
答案 0 :(得分:2)
代码是正确的,因此,考虑到您在控制台中看到installed
,唯一的解释是:
该网页已欺骗window.addEventListener
或附加了自己的'message'
听众,并在听众看到之前取消该活动(例如,使用event.stopPropagation()
等)。
在这种情况下,您需要声明内容脚本以运行before the page starts loading并使用一个侦听器来捕获事件,然后它在DOM链(useCapture
(第addEventListener
的第三个参数},应为true
)。
的manifest.json:
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content.js"],
"run_at": "document_start"
}],
content.js:
// this code runs before page starts loading
var injected = document.documentElement.appendChild(document.createElement('script'));
injected.text = '(' + function() {
window.addEventListener('message', function(ev) {
console.log('New event:', ev);
}, true); // useCapture: true
console.log('installed');
} + ')()';
injected.remove();
document.addEventListener('DOMContentLoaded', function() {
// this code will run when the DOM is ready
window.postMessage({ foo: 'bar', text: "Hello from content script!" }, "*");
});
请注意我们将脚本添加到documentElement
,因为document_start
通常没有head
。
另见:other methods of injecting a DOM script。