从内容脚本向页面 Javascript 发送消息
Sending messages to page Javascript from a content script
我在 Javascript 运行时中有一个选项卡方法,我想从我的扩展程序的内容脚本中触发该选项卡。从表面上看,这需要在上下文之间传递消息,但我找不到任何关于 CS 到选项卡消息的文档,只有选项卡到 CS 或 CS 到背景。本质上,我想翻转内容脚本参考的 Communication with the embedding page 部分。
到目前为止,我通过注入一个小的 Javascript 负载将事件监听器附加到选项卡的 window
(这将在正确的消息类型上触发选项卡方法):
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
创建一个端口,用于后台脚本。
如何以最简单的方式将消息从内容脚本传递到选项卡?
代码是正确的,因此,考虑到您在控制台中看到 installed
,唯一的解释是:
- 页面被重定向,整个 DOM 及其侦听器被销毁。
该页面欺骗了 window.addEventListener
或附加了自己的 'message'
侦听器,并在您的侦听器看到它之前取消了事件(例如,通过使用 event.stopPropagation()
等)
在这种情况下,您需要将内容脚本声明为 运行 before the page starts loading 并使用监听器在事件沿 DOM 链冒泡之前捕获事件(useCapture
, addEventListener
的第3个参数应该是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.
我在 Javascript 运行时中有一个选项卡方法,我想从我的扩展程序的内容脚本中触发该选项卡。从表面上看,这需要在上下文之间传递消息,但我找不到任何关于 CS 到选项卡消息的文档,只有选项卡到 CS 或 CS 到背景。本质上,我想翻转内容脚本参考的 Communication with the embedding page 部分。
到目前为止,我通过注入一个小的 Javascript 负载将事件监听器附加到选项卡的 window
(这将在正确的消息类型上触发选项卡方法):
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
创建一个端口,用于后台脚本。
如何以最简单的方式将消息从内容脚本传递到选项卡?
代码是正确的,因此,考虑到您在控制台中看到 installed
,唯一的解释是:
- 页面被重定向,整个 DOM 及其侦听器被销毁。
该页面欺骗了
window.addEventListener
或附加了自己的'message'
侦听器,并在您的侦听器看到它之前取消了事件(例如,通过使用event.stopPropagation()
等)在这种情况下,您需要将内容脚本声明为 运行 before the page starts loading 并使用监听器在事件沿 DOM 链冒泡之前捕获事件(
useCapture
,addEventListener
的第3个参数应该是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.