Javascript 如何跨域使用 window.postMessage?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3457391/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:42:55  来源:igfitidea点击:

How do you use window.postMessage across domains?

javascripthtmlgoogle-chromexss

提问by Kevin Montrose

It seems like the point of window.postMessageis to allow safe communication between windows/frames hosted on different domains, but it doesn't actually seem to allowthat in Chrome.

window.postMessage的重点似乎是允许托管在不同域上的窗口/框架之间进行安全通信,但实际上它似乎不允许在 Chrome 中进行。

Here's the scenario:

这是场景:

  1. Embed an <iframe> (with a srcon domain B*) in a page on domain A
  2. The <iframe> ends up being mostly a <script> tag, at the end of which's execution...
  3. I call window.postMessage( some_data, page_on_A)
  1. 在域 A 的页面中嵌入 <iframe>(src域 B *上有一个)
  2. <iframe> 最终主要是一个 <script> 标签,在其执行结束时......
  3. 我打电话给 window.postMessage( some_data, page_on_A)

The <iframe> is most definitely in the context of domain B, and I've confirmed that the embedded javascript in that <iframe> executes properly and calls postMessagewith the correct values.

<iframe> 绝对是在域 B 的上下文中,我已经确认 <iframe> 中嵌入的 javascript 可以正确执行并postMessage使用正确的值调用。

I get this error message in Chrome:

我在 Chrome 中收到此错误消息:

Unable to post message to A. Recipient has origin B.

无法向A发布消息。收件人有来源B

Here's the code that registers a message event listener in the page on A:

这是在 A 上的页面中注册消息事件侦听器的代码:

window.addEventListener(
  "message",
  function (event) {
    // Do something
  },
  false);

I've also tried calling window.postMessage(some_data, '*'), but all that does is suppress the error.

我也试过调用window.postMessage(some_data, '*'),但所做的只是抑制错误。

Am I just missing the point here, is window.postMessage(...) not meant for this? Or am I just doing it horribly wrong?

我是否只是错过了这一点, window.postMessage(...) 不是为此而设计的吗?还是我只是做错了可怕的事?

*Mime-type text/html, which it must remain.

* Mime-type text/html,它必须保留。

采纳答案by Mic

Here is an example that works on Chrome 5.0.375.125.

这是一个适用于 Chrome 5.0.375.125 的示例。

The page B (iframe content):

页面B(iframe内容):

<html>
    <head></head>
    <body>
        <script>
            top.postMessage('hello', 'A');
        </script>
    </body>
</html>

Note the use of top.postMessageor parent.postMessagenot window.postMessagehere

注意使用top.postMessageparent.postMessagewindow.postMessage这里

The page A:

页面A:

<html>
<head></head>
<body>
    <iframe src="B"></iframe>
    <script>
        window.addEventListener( "message",
          function (e) {
                if(e.origin !== 'B'){ return; } 
                alert(e.data);
          },
          false);
    </script>
</body>
</html>

A and B must be something like http://domain.com

A 和 B 必须是这样的 http://domain.com

EDIT:

编辑:

From another question, it looks the domains(A and B here) must have a /for the postMessageto work properly.

另一个问题来看,域(此处/为A 和 B)必须具有一个postMessage才能正常工作。

回答by Golyo

You should post a message from frame to parent, after loaded.

加载后,您应该从框架向父级发布消息。

frame script:

框架脚本:

$(document).ready(function() {
    window.parent.postMessage("I'm loaded", "*");
});

And listen it in parent:

并在父母中收听:

function listenMessage(msg) {
    alert(msg);
}

if (window.addEventListener) {
    window.addEventListener("message", listenMessage, false);
} else {
    window.attachEvent("onmessage", listenMessage);
}

Use this link for more info: http://en.wikipedia.org/wiki/Web_Messaging

使用此链接了解更多信息:http: //en.wikipedia.org/wiki/Web_Messaging

回答by Getoriks

Probably you try to send your data from mydomain.com to www.mydomain.com or reverse, NOTE you missed "www". http://mydomain.comand http://www.mydomain.comare different domains to javascript.

可能您尝试将数据从 mydomain.com 发送到 www.mydomain.com 或反向发送,注意您错过了“www”。http://mydomain.comhttp://www.mydomain.com是与 javascript 不同的域。