Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you use window.postMessage across domains?

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

Here's the scenario:

  1. Embed an <iframe> (with a src on 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 )

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 postMessage with the correct values.

I get this error message in Chrome:

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

Here's the code that registers a message event listener in the page on 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.

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

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

like image 748
Kevin Montrose Avatar asked Aug 11 '10 10:08

Kevin Montrose


People also ask

Does postMessage work cross-domain?

PostMessage() is a global method that safely enables cross-origin communication. It's a lot like Ajax but with cross-domain capability. We'll give it a whirl by setting up two-way communication between a web page and an iframe whose content resides on another server.

What is the use of window postMessage?

The window. postMessage() method safely enables cross-origin communication between Window objects; e.g., between a page and a pop-up that it spawned, or between a page and an iframe embedded within it.

What is cross window communication?

The “Same Origin” (same site) policy limits access of windows and frames to each other. The idea is that if a user has two pages open: one from john-smith.com , and another one is gmail.com , then they wouldn't want a script from john-smith.com to read our mail from gmail.com .


3 Answers

Here is an example that works on Chrome 5.0.375.125.

The page B (iframe content):

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

Note the use of top.postMessage or parent.postMessage not window.postMessage here

The page 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.example

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

like image 122
Mic Avatar answered Oct 25 '22 23:10

Mic


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

like image 28
Golyo Avatar answered Oct 25 '22 23:10

Golyo


Probably you try to send your data from mydomain.example to www.mydomain.example or reverse, NOTE you missed "www". http://mydomain.example and http://www.mydomain.example are different domains to JavaScript.

like image 2
Getoriks Avatar answered Oct 26 '22 01:10

Getoriks