无法使用Chrome扩展程序中的postMessage从父窗口向iframe发送数据

时间:2016-05-30 14:30:31

标签: javascript iframe google-chrome-extension cross-domain postmessage

我正在开发一个Google Chrome扩展程序,它在网页上注入脚本,从网页收集一些数据,调用iframe并将该数据发送到iframe。由于此过程需要跨域,因此postMessage是我唯一可以考虑实现此问题的方法,但我无法在iframe中接收此数据。
(顺便说一下,有没有我可以通过哪种方法实现相同的功能?)

下面是我在用户点击扩展程序时在网页上注入的脚本。

jQuery('body').append('<div style="height: 100% !important; width: 100% !important; position: fixed !important; margin: 0% auto !important; background: rgba(17, 17, 17, 0.9) !important; left: 0 !important; right: 0 !important; z-index: 99999999 !important; top: 0% !important;" id="image-grabber-container"><iframe id="vwframe" src="https://example.com/abcd.php"  frameborder="0" style="display: block !important; position: fixed !important; height: 100% !important; width: 100% !important; top: 0px !important; left: 0px !important; bottom: 0px !important; right: 0px !important; margin: 0px !important; clip: auto !important; z-index: 7147483657 !important;"></iframe></div>');

setTimeout(function(){
    var dTitle = document.title;
    var receiver = document.getElementById('vwframe').contentWindow;
    receiver.postMessage(dTitle, '*');
},1000);


我在这里使用setTimeout只是为了确保在发布消息时iframe可用/已加载。

现在,我调用iframe中的脚本来接收消息:

window.onload = function() {
        function receiveMessage1(e) {
            console.log('mSG');
            if (e.origin !== currentUrl)
                return;

            parentTitle = e.data;
            console.log(parentTitle);
        }
        if (window.addEventListener){
            console.log('if');
          window.addEventListener("message", receiveMessage1, false);
          console.log('if end');
        } else {
            console.log('else');
          attachEvent("onmessage", receiveMessage1);
          console.log('else end');
        }
}


我在控制台中看不到任何错误,但receiveMessage1函数无法正常工作。可能的原因是什么?

P.S。我能够从iframe向父母发送消息,但反之亦然。

2 个答案:

答案 0 :(得分:1)

请尝试不使用setTimeout和window.onload,而是使用:

<script>

    function receiveMessage1(e) {
        console.log('mSG');
        if (e.origin !== currentUrl)
            return;

        parentTitle = e.data;
        console.log(parentTitle);
    }
    if (window.addEventListener){
        console.log('if');
      window.addEventListener("message", receiveMessage1, false);
      console.log('if end');
    } else {
        console.log('else');
      attachEvent("onmessage", receiveMessage1);
      console.log('else end');
    }
</script>

答案 1 :(得分:0)

在我看来,使用postMessage()方法仍然是跨域传递邮件的更安全的方法。

要使用此方法,请注意它接受两个参数:

  • message - 将发送给接收方的字符串或对象 窗口。
  • targetOrigin - 正在发送邮件的窗口的URL 至。目标窗口的协议,端口和主机名必须匹配 要发送的消息的此参数。指定“*”将匹配 但是出于安全原因,强烈建议不要这样做。

并且,应该在消息设置的窗口上调用此方法。可以通过多种不同方式获得对目标窗口的引用:

  • 使用window.open()时,将会引用新窗口 由open()方法返回。
  • 对于iframe,您可以访问所需的contentWindow属性 iframe中。
      

    targetWindow.postMessage('Hello World!', 'http://example.com');

此博客中提供了使用提示,有关实施的更多信息和完整指南 - Cross-Domain Messaging With postMessage,我认为此SO帖子 - Invoking JavaScript code in an iframe from the parent page也会有所帮助。