Javascript IE11上的postMessage仍然中断?
在IE 11上发送消息时,window.postMessage似乎仍处于中断状态Javascript IE11上的postMessage仍然中断?,javascript,internet-explorer,cross-browser,cross-domain,postmessage,Javascript,Internet Explorer,Cross Browser,Cross Domain,Postmessage,在IE 11上发送消息时,window.postMessage似乎仍处于中断状态 在窗口和带有window.open的子弹出窗口/选项卡之间 当它从不同的域发送时[或者在某些情况下是从同一域发送,c.f.更新16/01] IE8/9/10也存在类似的问题,但该功能在IE11中从IE10中的“部分支持”标记为“支持” 下面是一个适用于chrome/ff但不适用于IE的代码示例: 委员会: (如果不是由JSFIDLE打开,则不会工作) 我从帖子中读到,我们可以使用MessageChannel而不
- 在窗口和带有window.open的子弹出窗口/选项卡之间
- 当它从不同的域发送时[或者在某些情况下是从同一域发送,c.f.更新16/01]
MessageChannel
而不是postMessage
,但是在阅读文档时,我没有发现如何在我的实际案例中使用它,因为您必须将端口传递给子窗口
在我需要发送消息之前有一个重定向链,因此即使我可以发送端口,我也会丢失最初/重定向之前发送的任何js对象
有没有替换的想法
更新14/01:我正在考虑在窗口/选项卡标题中传递我的数据,并定期从父窗口检查此标题。。。但这将是一个相当肮脏的把戏
更新16/01:真正糟糕的部分是,即使消息是从同一个域发送的,但在被另一个域重定向后,它也会出现盈亏平衡
以下是一个例子:
打开重定向到(发布消息)的弹出窗口
如果您直接更改url弹出窗口,则最终url将重定向到IE上的此项,因为在打开和发布之间没有其他域
我仍然在做我的窗口标题肮脏的把戏。当窗口在另一个域上时,我们无法接收它的标题,但是如果它在JSFIDLE上返回,则标题是可用的(postMessage没有以前的问题)。下面是一个例子:。。。这可能是另一种解决方案,但我刚刚看到了一些关于在cookie中传递数据的内容,它只需要进行测试
更新04/02:在标题中传递信息是不够的,如果最终域相同但不在跨域中,则if效果良好。我想注入同一域的iframe来传递这些信息,但我也不能共享子窗口对象(postMessage需要一个可序列化的对象)
最后,我尝试在注入的iframe和子窗口之间共享一个cookie(在js中创建和接收),这在chrome和ff上运行良好,但在IE中仍然无法正确接收。添加P3P头后,它运行良好,这似乎是真正的解决方案。Safari似乎在这项技术上有一些问题,所以我保留这项技术作为备用。它坏了吗?嗯,有点 我尝试了各种各样的想法,但无法让您的中的代码正常工作。看看这一点,我们发现
postMessage
只在IE的旧版本中的iFrame之间起作用,而IE 11的iFrame尚未修复
那篇文章与这个问题的一个重要方面相联系。有两种解决方法涉及在窗口.opener
上调用脚本。然而,正如该博客所述(我的重点):
不幸的是,这种解决方法通常是不可能的,因为同源策略规定弹出窗口和window.opener页面必须来自同一个源,才能调用彼此的脚本函数
因此,看起来唯一的方法是,在父对象的IFrame中托管子对象。我根据你的代码创建了一个类似的演示。这很简单,但是会向IFrame的contentWindow
发布一条消息,然后IFrame会做出响应
我看到了使用MessageChannel
的建议,但我也怀疑使用是否值得研究,尽管它们的使用当然取决于任务的性质。对于这个问题也有答案,使用了IFrame方法,但是使用了jqueryui对话框来显示它——我想如果您愿意的话,您可以在Bootstrap中对modals做同样的事情
供参考: 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');
});
});
var-wnd;
$(文档).ready(函数(){
$('#log').append('listening…');
wnd=$('#iframe')[0].contentWindow;
window.addEventListener('message',函数(e){
$('#log').append('
收到的消息:'+JSON.stringify(e.data));
},假);
$(“#发布消息按钮”)。单击(函数(){
如果(!wnd){
返回;
}
$('#log')。追加('
发送…');
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>
JS-Bin
$(文档).ready(函数(){
window.addEventListener(“消息”,函数(e){
$('body').append('
Origin:'+e.Origin);
$('body').append(
收到的消息:“+JSON.stringify(e.data));
e、 source.postMessage('Hello yourself',e.origin);
},假);
});
更新16/01:真正糟糕的部分是,即使消息是从同一个域发送的,但在被另一个域重定向后,它也会出现盈亏平衡
有趣的是,这个“安全特性”可以反过来完全绕过跨域限制
在位于example.com
的父窗口中:
<script>
window.open("http://example.com/dummy_redirect");
window.addEventListener('message', function(ev) {console.log(ev.data)})
</script>
弹出窗口将打开到您的域,重定向到JSFIDLE,postMessage调用将在IE中工作。在此之后,您甚至可以导航到任何域,并继续对父窗口进行postMessage调用。有几处提到了
iframe
解决方案,但我所见过的唯一一个是向iframe
发送消息
以下是从iframe
接收消息的示例:
父页面(http&colon;//first domain.com/receive message.html)
window.addEventListener
<!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>
<script>
window.open("http://example.com/dummy_redirect");
window.addEventListener('message', function(ev) {console.log(ev.data)})
</script>
GET /dummy_redirect 302 http://jsfiddle.net/b6yfbunw/
<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>
<html>
<head>
<script>
window.parent.postMessage('hi there', '*');
</script>
</head>
<body></body>
</html>