消息出现时,IE11上的window.postMessage似乎仍然中断。
IE8/9/ 10也有类似的问题,但是这个特性在IE 11中被标记为“支持”,而在IE10中被标记为“部分支持”。
有一个在chrome/ff上工作的代码示例,但不适用于IE:
The 开瓶器(小提琴)
$(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):(如果不是被小提琴打开的话就不能工作)
$(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似乎在这项技术上有一些问题,所以我只保留这项技术作为后盾。
发布于 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做同样的事情。
供参考:
<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>
发布于 2014-09-04 18:56:10
更新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调用。
发布于 2016-09-15 12:40:12
有几处提到了iframe
的解决方案,但我看到的唯一一处是向iframe
发送消息。
下面是一个从iframe
接收消息的示例:
父页 (http://first-domain.com/receive-message.html)
<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)
<html>
<head>
<script>
window.parent.postMessage('hi there', '*');
</script>
</head>
<body></body>
</html>
https://stackoverflow.com/questions/21070553
复制相似问题