首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >postMessage还在IE11上崩溃吗?

postMessage还在IE11上崩溃吗?
EN

Stack Overflow用户
提问于 2014-01-12 02:24:15
回答 4查看 32.4K关注 0票数 29

消息出现时,IE11上的window.postMessage似乎仍然中断。

  • 在窗口和子窗口之间使用window.open弹出/选项卡
  • 当它从不同的域()或相同的域(在某些情况下是相同的域)发送时,c.f。更新16/01

IE8/9/ 10也有类似的问题,但是这个特性在IE 11中被标记为“支持”,而在IE10中被标记为“部分支持”。

有一个在chrome/ff上工作的代码示例,但不适用于IE:

The 开瓶器(小提琴)

代码语言:javascript
运行
复制
$(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, width=200, height=100');
    });
});

子弹出(jsbin):(如果不是被小提琴打开的话就不能工作)

代码语言:javascript
运行
复制
$(document).ready(function() {
   $('body').append('sending...');
   window.opener.postMessage("Hello?", "http://fiddle.jshell.net");
   $('body').append('sent...');
});

我从post 跨原点postMessage在IE10中被破坏了吗?中看到,我们可以使用MessageChannel而不是postMessage,但是阅读文档时,我没有找到如何在实际情况下使用它,因为您必须将端口传递给子窗口。

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

想不想换个人?

更新14/01:我正在考虑将我的数据传递到窗口/选项卡标题中,并定期从父目录中检查此标题.但这是个肮脏的诡计。

Update 16/01:真正糟糕的是,如果消息是从同一个域发送的,但是在被另一个域重定向之后,它确实会中断。

下面是示例:http://jsfiddle.net/L4YzG/13/打开重定向到http://jsfiddle.net/mxS8Q/2/ (发布消息)的弹出http://jsbin.com/eQeSeros/4/edit

如果您通过最终的url重定向将url弹出直接更改为http://jsfiddle.net/mxS8Q/2/show,则此操作在IE上有效,因为在开头和post之间没有其他域。

我还在忙我的窗口标题肮脏的把戏。当窗口位于另一个域时,我们无法接收它的标题,但是如果它在jsfiddle上返回,则标题是可用的(postMessage没有前面的问题)。下面是一个例子:http://jsfiddle.net/L4YzG/14/ ..。这可能是另一种解决方案,但我刚刚看到了在cookie中传递数据的一些内容,它只是需要进行测试。

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

最后,我尝试在注入的iframe和子窗口之间共享一个cookie (在js中创建和接收),这在chrome & ff上工作得很好,但是仍然不能在IE中正确地接收它。在添加P3P头之后,它工作得很好,这似乎是真正的解决方案。Safari似乎在这项技术上有一些问题,所以我只保留这项技术作为后盾。

EN

回答 4

Stack Overflow用户

发布于 2014-01-16 00:01:17

它坏了吗?嗯,算是吧。

我尝试了各种想法,但无法让您的jsFiddle中的代码工作。查看这个MSDN博客文章,我们发现postMessage只在较早版本的IE中在IFrames之间工作,而IE 11尚未修复。

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

不幸的是,这种解决方法通常是不可能的,因为相同的源策略要求弹出窗口和window.opener页面必须来自同一个原始,以便相互调用对方的脚本函数。

因此,看起来唯一的方法是类似于,其子节点托管在父级的IFrame中。我已经创建了一个类似的演示这里,基于您的代码。这很简单,但会向contentWindow of IFrame发布一条消息,而后者又会做出响应。

我看到了使用MessageChannel的建议,但我也想知道使用网络工作者是否值得研究,尽管它们的使用当然取决于任务的性质。还有这个问题的答案,其中使用了IFrame方法,但是使用了一个jQuery UI对话框来显示它--如果您愿意的话,我可以想象您可以在Bootstrap中对modals做同样的事情。

供参考:

代码语言:javascript
运行
复制
<iframe id="iframe" src="http://jsbin.com/iLapokOS/7/"></iframe>
<div id="log"></div>
<button id="post-message-button">Post message to window</button>

父脚本

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
<!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>
票数 16
EN

Stack Overflow用户

发布于 2014-09-04 18:56:10

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

有趣的是,这种“安全特性”可以反向使用,完全绕过跨域限制。

example.com的父窗口中

代码语言:javascript
运行
复制
<script>
  window.open("http://example.com/dummy_redirect");
  window.addEventListener('message', function(ev) {console.log(ev.data)})
</script>

example.com服务器上:

代码语言:javascript
运行
复制
GET /dummy_redirect 302 http://jsfiddle.net/b6yfbunw/

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

票数 16
EN

Stack Overflow用户

发布于 2016-09-15 12:40:12

有几处提到了iframe的解决方案,但我看到的唯一一处是向iframe发送消息。

下面是一个从iframe接收消息的示例:

父页 (http://first-domain.com/receive-message.html)

代码语言:javascript
运行
复制
<html>
  <head>
    <script>
      window.addEventListener('message', console.log.bind(console, 'Got message:'));
    </script>
  </head>
  <body>
    <iframe src="http://second-domain.com/send-message.html"></iframe>
  </body>
</html>

Child-page (http://second-domain.com/send-message.html)

代码语言:javascript
运行
复制
<html>
  <head>
    <script>
      window.parent.postMessage('hi there', '*');
    </script>
  </head>
  <body></body>
</html>
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21070553

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档