我正在尝试让一个微不足道的postMessage
示例工作……
窗口/选项卡之间的iframes)
对比
删除这些条件中的任何一个,事情就可以正常工作了:-)
但据我所知,只有当两个窗口共享一个原点时,窗口间的postMessage
才能在IE10中工作。(实际上,奇怪的是,这种行为比这稍微宽松一些:共享一个宿主的两个不同的起源似乎也是有效的)。
这是一个记录在案的bug吗?有什么变通方法或其他建议吗?
(注意:This question谈到了问题,但its answer是关于IE8和IE9的--而不是10)
更多细节+示例...
启动器页面demo
<!DOCTYPE html>
<html>
<script>
window.addEventListener("message", function(e){
console.log("Received message: ", e);
}, false);
</script>
<button onclick="window.open('http://jsbin.com/ameguj/1');">
Open new window
</button>
</html>
已启动页面demo
<!DOCTYPE html>
<html>
<script>
window.opener.postMessage("Ahoy!", "*");
</script>
</html>
这适用于:http://jsbin.com/ahuzir/1 --因为两个页面都托管在相同的源(jsbin.com)上。但是将第二个页面移到其他任何地方,在IE10中都会失败。
发布于 2013-05-01 13:49:48
当我最初发布这个答案时,我弄错了:它实际上在IE10中不起作用。显然,人们出于其他原因发现它很有用,所以我把它留给子孙后代。原始答案如下:
值得一提的是:您链接到的答案中的链接表明,postMessage
不是IE8和IE9中独立窗口的交叉来源--然而,它也是在IE10出现之前的2009年编写的。所以我不会认为这是在IE10中修复的迹象。
至于postMessage
本身,http://caniuse.com/#feat=x-doc-messaging特别指出它在IE10中仍有缺陷,这似乎与您的演示相符。caniuse页面链接到this article,其中包含一个非常相关的引用:
iframes 8+部分支持跨文档消息传递:它目前支持iframes,但不支持新的windows。然而,Internet Explorer10将支持MessageChannel。火狐目前支持跨文档消息传递,但不支持MessageChannel。
因此,您最好的选择可能是拥有一个基于MessageChannel
的代码路径,如果postMessage
不存在,则回退到它。它不会让你支持IE8/IE9,但至少它可以在IE10上工作。
MessageChannel
上的文档:http://msdn.microsoft.com/en-us/library/windows/apps/hh441303.aspx
发布于 2014-07-01 21:39:37
在launcher所在的主机上创建代理页面。代理页面具有源设置为远程页面的iframe
。现在跨域postMessage在IE10中的工作方式如下:
window.parent.postMessage
将数据传递到代理页面。由于这使用了iframes,因此受到IE10的支持,
window.opener.postMessage
将数据传回启动程序页面。因为这是在同一个域上-没有跨域问题。如果你不想使用postMessage - eg,它也可以直接调用启动器页面上的全局方法。window.opener.someMethod(data)
示例(所有URL都是虚构的)
http://example.com/launcher.htm
上的启动程序页面
<!DOCTYPE html>
<html>
<head>
<title>Test launcher page</title>
<link rel="stylesheet" href="/css/style.css" />
</head>
<body>
<script>
function log(msg) {
if (!msg) return;
var logger = document.getElementById('logger');
logger.value += msg + '\r\n';
}
function toJson(obj) {
return JSON.stringify(obj, null, 2);
}
function openProxy() {
var url = 'proxy.htm';
window.open(url, 'wdwProxy', 'location=no');
log('Open proxy: ' + url);
}
window.addEventListener('message', function(e) {
log('Received message: ' + toJson(e.data));
}, false);
</script>
<button onclick="openProxy();">Open remote</button> <br/>
<textarea cols="150" rows="20" id="logger"></textarea>
</body>
</html>
http://example.com/proxy.htm
上的Proxy页面
<!DOCTYPE html>
<html>
<head>
<title>Proxy page</title>
<link rel="stylesheet" href="/css/style.css" />
</head>
<body>
<script>
function toJson(obj) {
return JSON.stringify(obj, null, 2);
}
window.addEventListener('message', function(e) {
console.log('Received message: ' + toJson(e.data));
window.opener.postMessage(e.data, '*');
window.close(self);
}, false);
</script>
<iframe src="http://example.net/remote.htm" frameborder="0" height="300" width="500" marginheight="0" marginwidth="0" scrolling="auto"></iframe>
</body>
</html>
位于 http://example.net/remote.htm
的Remote页
<!DOCTYPE html>
<html>
<head>
<title>Remote page</title>
<link rel="stylesheet" href="/css/style.css" />
</head>
<body>
<script>
function remoteSubmit() {
var data = {
message: document.getElementById('msg').value
};
window.parent.postMessage(data, '*');
}
</script>
<h2>Remote page</h2>
<input type="text" id="msg" placeholder="Type a message" /><button onclick="remoteSubmit();">Close</button>
</body>
</html>
发布于 2016-04-15 01:29:52
2020年不使用iframe ==的==工作解决方案
基于tangle的answer构建,我使用以下代码片段成功地使用了IE11和模拟的IE10模式:
var submitWindow = window.open("/", "processingWindow");
submitWindow.location.href = 'about:blank';
submitWindow.location.href = 'remotePage to communicate with';
然后我可以使用典型的postMessage堆栈进行通信,在我的场景中我使用了一个全局静态信使(尽管我不认为它有任何意义,但我也附加了我的信使类)
var messagingProvider = {
_initialized: false,
_currentHandler: null,
_init: function () {
var self = this;
this._initialized = true;
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
eventer(messageEvent, function (e) {
var callback = self._currentHandler;
if (callback != null) {
var key = e.message ? "message" : "data";
var data = e[key];
callback(data);
}
}, false);
},
post: function (target, message) {
target.postMessage(message, '*');
},
setListener: function (callback) {
if (!this._initialized) {
this._init();
}
this._currentHandler = callback;
}
}
无论我怎么努力,我都不能在IE9和IE8上工作
我的配置在它工作的地方:
IE版本: 11.0.10240.16590,更新版本: 11.0.25 (KB3100773)
https://stackoverflow.com/questions/16226924
复制相似问题