从内容脚本发送消息到页面javascript

时间:2016-09-19 21:06:54

标签: google-chrome-extension javascript-events content-script

我在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创建一个端口,用于后台脚本。

如何以最简单的方式将消息从内容脚本传递到选项卡?

1 个答案:

答案 0 :(得分:2)

代码是正确的,因此,考虑到您在控制台中看到installed,唯一的解释是:

  1. 页面被重定向,整个DOM及其侦听器被破坏。
  2. 该网页已欺骗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