为什么 html5 postMessage 对我不起作用?

发布于 2024-11-08 02:44:10 字数 1354 浏览 0 评论 0原文

我使用几行 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

誰認得朕 2024-11-15 02:44:10

有两个可能的问题:

  1. 您在子框架加载之前调用 callback - 在 load 事件中尝试或在 setTimeout 中执行>
  2. 我从未设法让 postMessage 与“*”以外的任何其他内容一起工作。如果我在其中输入 URL,则会收到安全警告“安全错误:http://xxx/ 处的内容可能无法加载数据”来自 http://yyy/",除了仅在错误控制台 (Ctrl + Shift + J) 中,而不是在任何其他地方。我怀疑还需要在某个地方设置一些其他东西才能发挥作用,但我还没有弄清楚是什么。

这是一个 jsfiddle ,其中代码的版本略有修改,可从我的域加载文档,适用于我火狐和 Chrome。

There are two possible problems:

  1. You're calling callback before the child frame has loaded - try it in the load event or do it in a setTimeout
  2. I've never managed to get 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.

笑忘罢 2024-11-15 02:44:10

我们的测试设置中出现的一个问题是,放置 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.

煮茶煮酒煮时光 2024-11-15 02:44:10

我知道这已经很晚了,但为了将来......

当您从 Iframe 发布消息时,源不是 iframe 的域,而是父级的(目标源)。

示例:父级的域是 http://parent.local 且 Iframe 是 http://iframe.local

从 IFrame 发布到父级并且仅有效父级

window.parent.postMessage({foo: 12}, 'http://parent.local') // note the domain. we want to talk to only that domain / target origin

父级可以通过检查 MessageEvent 上的 origin 属性来确认请求来自有效的 iframe

window.addEventListener('message', (event) => {
 console.log(event.origin) // will be http://iframe.local
})

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 is http://iframe.local

To post from the IFrame to the parent and only the valid parent:

window.parent.postMessage({foo: 12}, 'http://parent.local') // note the domain. we want to talk to only that domain / target origin

The parent can confirm that the request came from a valid iframe by checking the origin property on the MessageEvent

window.addEventListener('message', (event) => {
 console.log(event.origin) // will be http://iframe.local
})
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文