为什么 html5 postMessage 对我不起作用?
我使用几行 javascript 来创建一个 iframe 元素,然后我想向它发送一条消息,如下所示:
function loadiframe (callback) {
var body = document.getElementsByTagName('body')[0];
var iframe = document.createElement('iframe');
iframe.id = 'iframe';
iframe.seamless = 'seamless';
iframe.src = 'http://localhost:3000/iframe.html';
body.appendChild(iframe);
callback();
}
loadiframe(function() {
cpframe = document.getElementById('iframe').contentWindow;
cpframe.postMessage('please get this message','http://localhost:3000');
console.log('posted');
})
然后,在 http://localhost:3000/iframe.html(iframe的来源)是这样的:
<!DOCTYPE html>
<html>
<head>
<title>does not work</title>
<script>
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event) {
if (event.origin == "http://localhost:3000") {
document.write(JSON.stringify(event));
document.write(typeof event);
}
}
</script>
</head>
<body>
</body>
</html>
但是什么也没发生...我什至尝试不使用来源安全检查,但即使这样什么也没有发生...就像它从未收到消息...
我是否遇到了某种异步问题?我试图确保在 postMessage 消失之前加载 iframe...
编辑 1:另外,控制台上没有显示错误...
编辑 2:我在 Google Chrome 11 和 Firefox 4 中尝试过,
提前谢谢您。
I use a few lines of javascript to create an iframe element, and then I'd like to send it a message, like this:
function loadiframe (callback) {
var body = document.getElementsByTagName('body')[0];
var iframe = document.createElement('iframe');
iframe.id = 'iframe';
iframe.seamless = 'seamless';
iframe.src = 'http://localhost:3000/iframe.html';
body.appendChild(iframe);
callback();
}
loadiframe(function() {
cpframe = document.getElementById('iframe').contentWindow;
cpframe.postMessage('please get this message','http://localhost:3000');
console.log('posted');
})
And then, inside http://localhost:3000/iframe.html (the source of the iframe) is something like this:
<!DOCTYPE html>
<html>
<head>
<title>does not work</title>
<script>
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event) {
if (event.origin == "http://localhost:3000") {
document.write(JSON.stringify(event));
document.write(typeof event);
}
}
</script>
</head>
<body>
</body>
</html>
But nothing happens... I even tried to not use the safety check for origin, but even like that nothing happens... Like it never got the message...
Am I in some kind of async problem ? I tried to make sure the iframe was loaded before the postMessage went away...
EDIT1: Also, no errors show on the console...
EDIT2: I tried it in Google Chrome 11 and Firefox 4
Thank you in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
有两个可能的问题:
callback
- 在load
事件中尝试或在setTimeout
中执行>postMessage
与“*”以外的任何其他内容一起工作。如果我在其中输入 URL,则会收到安全警告“安全错误:http://xxx/ 处的内容可能无法加载数据”来自 http://yyy/",除了仅在错误控制台 (Ctrl + Shift + J) 中,而不是在任何其他地方。我怀疑还需要在某个地方设置一些其他东西才能发挥作用,但我还没有弄清楚是什么。这是一个 jsfiddle ,其中代码的版本略有修改,可从我的域加载文档,适用于我火狐和 Chrome。
There are two possible problems:
callback
before the child frame has loaded - try it in theload
event or do it in asetTimeout
postMessage
to work with anything other that '*' as the origin. If I put a URL in there I get a security warning "Security Error: Content at http://xxx/ may not load data from http://yyy/", except only in the error console (Ctrl + Shift + J) not in any other place. I suspect there's some other stuff that needs set up somewhere for that to work, but I've not yet figured out what.Here's a jsfiddle with a slightly modified version of your code loading a document off my domain, works for me in Firefox and Chrome.
我们的测试设置中出现的一个问题是,放置 iFrame 的托管测试站点是通过文件系统提供服务的。因此我们切换到 Apache 通过 localhost 提供服务。
iFrame 内的应用程序是一个 Angular 应用程序:用于从 window.parent 接收事件的事件处理程序绑定在 Angular 应用程序的 ngOnInit 方法内。那也行不通。需要将事件处理程序附加到index.html 中的脚本块内。
One problem that occured in our test setup was the fact that the hosting test site where the iFrame was placed was served via the file system. So we switched to Apache to serve it via localhost.
The application inside the iFrame was an Angular application: The event handler for receiving events from window.parent was bind inside the Angular applications ngOnInit method. That also was not working. It was needed to attach the event handler inside a script block in index.html.
我知道这已经很晚了,但为了将来......
当您从 Iframe 发布消息时,源不是 iframe 的域,而是父级的(目标源)。
示例:父级的域是
http://parent.local
且 Iframe 是http://iframe.local
从 IFrame 发布到父级并且仅有效父级:
父级可以通过检查 MessageEvent 上的 origin 属性来确认请求来自有效的 iframe
I know this is very late but for the future sake...
When you are posting a message from an Iframe, the origin is not the iframe's domain but the parent's (target origin).
Example: Parent's domain is
http://parent.local
and Iframe ishttp://iframe.local
To post from the IFrame to the parent and only the valid parent:
The parent can confirm that the request came from a valid iframe by checking the origin property on the MessageEvent