在IE11上,postMessage仍然被打破?

 书友68610983 发布于 2023-02-04 13:24

当消息出现时,似乎window11上的window.postMessage仍然被破坏

在window.open窗口和子弹出/选项卡之间

当它从不同的域发送[或在某些情况下相同的域,cf update 16/01]

IE 8/9/10也存在类似的问题,但IE 11中的"部分支持"在IE 11中标记为"支持"

有一个代码的例子适用于chrome/ff但不适用于IE:

在揭幕战(的jsfiddle) :

$(document).ready(function() {
    $('#log').append('listening...');
    window.addEventListener("message", function(e){
        $('#log').append("Received message: " + JSON.stringify(e.data));
    }, false);
    $('button').click(function() {
        window.open('http://jsbin.com/eQeSeros/1', 'popup','menubar=no, status=no, scrollbars=no, menubar=no, );
    });
});

该子弹出(jsbin) :(如果没有被打开的jsfiddle将无法正常工作)

$(document).ready(function() {
   $('body').append('sending...');
   window.opener.postMessage("Hello?", "http://fiddle.jshell.net");
   $('body').append('sent...');
});

我从帖子中读到了IE10中的跨源postMessage?我们可以使用a MessageChannel代替postMessage,但是阅读doc,我在实际情况下没有找到如何使用它,因为你必须将端口传递给子窗口.

在我需要发送消息之前有一个重定向链,所以即使我可以发送一个端口,我将丢失最初/重定向之前发送的任何js对象.

有没有替换的想法?

更新14/01:我正在考虑在窗口/标签标题中传递我的数据并定期检查父标题中的这个标题......但这将是一个非常脏的技巧.

更新16/01:真正糟糕的部分是,即使消息是从同一个域发送,但在被另一个域重定向后,它确实会中断.

这是一个例子:http: //jsfiddle.net/L4YzG/13/打开弹出窗口http://jsbin.com/eQeSeros/4/edit重定向到http://jsfiddle.net/mxS8Q/2/(那个发布消息)

如果您通过最终URL重定向直接更改url popup到http://jsfiddle.net/mxS8Q/2/show这适用于IE,因为在开放和发布之间没有其他域

我还在处理我的窗口标题脏伎俩.当它在另一个域上时,我们无法接收窗口的标题,但如果它返回到jsfiddle,则标题可用(postMessage之前没有问题).这是一个例子:http://jsfiddle.net/L4YzG/14/ ...这可能是一个替代解决方案,但我刚看到一些关于在cookie中传递数据的事情,它只需要进行测试.

更新04/02:如果最终域相同但不在跨域中,则在标题中传递信息是不够的.我想注入一个相同域的iframe来传递这些信息,但我也不能共享子窗口对象(postMessage需要一个可序列化的对象).

最后我尝试在注入的iframe和子窗口之间共享一个cookie(在js中创建和接收),这在chrome和ff上工作得很好,但仍然无法用IE正确接收它.添加P3P头后它工作正常,这似乎是真正的解决方案.Safari似乎对这种技术有一些问题所以我只是将这种技术作为后备.

2 个回答
  • 它坏了吗?好吧,有点.

    我尝试了各种各样的想法,无法让你的jsFiddle中的代码工作.看看这篇MSDN博客文章,我们发现postMessage只能在旧版IE中的IFrame之间工作,IE11尚未修复.

    那篇文章链接到问题的演示.有几种解决方法涉及调用脚本window.opener.然而,正如该博客所述(强调我的):

    遗憾的是,这种解决方法通常是不可能的,因为同源策略规定弹出窗口和window.opener页面必须来自同一个来源才能调用彼此的脚本函数.

    所以看起来这样做的唯一方法就是这样,其中孩子托管在父母的IFrame中.我在这里根据您的代码创建了一个类似的演示.它非常简单,但会contentWindow向IFrame 发送消息,而IFrame又会响应.

    我看到建议使用MessageChannel,但我也想知道使用Web Workers是否值得调查,尽管它们的使用当然取决于你的任务的性质.还有这个问题的答案,其中使用了IFrame方法,但是使用jQuery UI对话框来显示它 - 我想如果您愿意,可以使用Bootstrap中的模态执行相同的操作.


    以供参考:

    HTML

    <iframe id="iframe" src="http://jsbin.com/iLapokOS/7/"></iframe>
    <div id="log"></div>
    <button id="post-message-button">Post message to window</button>
    

    父脚本

    var wnd;
    
    $(document).ready(function() {
        $('#log').append('listening...');
    
        wnd = $('#iframe')[0].contentWindow;
    
        window.addEventListener('message', function(e){
          $('#log').append('<br/>Received message: ' + JSON.stringify(e.data));
        }, false);
    
        $('#post-message-button').click(function() {
            if(!wnd){
                return;
            }
            $('#log').append('<br/>sending...');
            wnd.postMessage('Hello?', 'http://jsbin.com');
        });
    });
    

    子HTML和JS

    <!DOCTYPE html>
    <html>
    <head>
    <script src="http://code.jquery.com/jquery-latest.js"></script>
    <meta charset=utf-8 />
    <title>JS Bin</title>
    </head>
    <body>
      <script>
        $(document).ready(function() {
    
          window.addEventListener("message", function(e){
            $('body').append('<br/>Origin: ' + e.origin);        
            $('body').append("<br/>Received message: " + JSON.stringify(e.data));
    
            e.source.postMessage('Hello yourself', e.origin);
          }, false);
        });
      </script>
    
    
    </body>
    </html>
    

    2023-02-04 13:26 回答
  • 更新16/01:真正糟糕的部分是,即使消息是从同一个域发送,但在被另一个域重定向后,它确实会中断.

    有趣的是,这种"安全功能"可以反过来用来完全绕过跨域限制.

    在父窗口中example.com:

    <script>
      window.open("http://example.com/dummy_redirect");
      window.addEventListener('message', function(ev) {console.log(ev.data)})
    </script>
    

    example.com服务器上:

    GET /dummy_redirect 302 http://jsfiddle.net/b6yfbunw/
    

    弹出窗口将打开您的域,重定向到jsfiddle,postMessage调用将在IE中工作.您甚至可以在此之后导航到任何域,并继续对父窗口进行postMessage调用.

    2023-02-04 13:26 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有