似乎当消息在以下情况下被发送时,window.postMessage 在 IE 11 上仍然存在问题:
- 在窗口和使用 window.open 打开的子弹出窗口/选项卡之间
- 当消息从不同的域中发送 [或者某些情况下是相同的域,参见更新16/01]
IE 8/9/10也存在类似问题,但该功能在 IE 11 中从 IE 10 的“部分支持”标记为“支持”。
这里有一个在 chrome / ff 上工作但在 IE 上不起作用的代码示例:
$(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):(如果不是通过jsfiddle打开,则无法正常工作)
$(document).ready(function() {
$('body').append('sending...');
window.opener.postMessage("Hello?", "http://fiddle.jshell.net");
$('body').append('sent...');
});
我从这篇帖子中读到,我们可以使用MessageChannel
代替postMessage
,但是看文档时,我没有找到如何在我的实际情况中使用它,因为你必须将端口传递给子窗口。
在我需要发送消息之前,有一个重定向链,所以即使我能发送一个端口,我仍然会失去最初/重定向之前发送的任何js对象。
有什么替代方案吗?
更新14/01: 我正在考虑在窗口/选项卡标题中传递我的数据,并经常从父级检查此标题...但这将是相当不道德的。
更新16/01: 真正糟糕的部分是,即使从同一域发送消息,但在通过另一个域重定向后也会出现问题。
以下是示例: http://jsfiddle.net/L4YzG/13/打开弹出窗口http://jsbin.com/eQeSeros/4/edit,然后重定向到http://jsfiddle.net/mxS8Q/2/(发送消息)
如果你直接将弹出窗口的URL更改为最终的URL,重定向到http://jsfiddle.net/mxS8Q/2/show,这在IE上可以工作,因为在打开和发布之间没有其他域。
我仍在研究如何通过窗口标题来实现“脏技巧”。当窗口处于另一个域时,我们无法接收到窗口的标题,但是如果它回到jsfiddle上,则标题可用(postMessage不会出现之前的问题)。这是一个示例:http://jsfiddle.net/L4YzG/14/ ... 这可能是一种替代方案,但我刚刚看到有关将数据传递给cookie的内容,只需要进行测试。
更新04/02:在标题中传递信息是不够的,在最终域相同的情况下效果很好,但在跨域情况下却不行。我想注入一个相同域的iframe来传递这些信息,但我也无法共享子窗口对象(postMessage需要一个可序列化对象)。
最后,我尝试在js中创建并接收cookie,并在注入的iframe和子窗口之间共享cookie,在Chrome和Firefox上运行良好,但在IE上仍然无法正确接收。添加P3P头之后,它就可以正常工作了,这似乎是真正的解决方法。Safari对这种技术似乎存在一些问题,因此我将这种技术作为备用方案。