How do you use window.postMessage across domains?

152,739

Solution 1

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.

Solution 2

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

Solution 3

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.

Share:
152,739
Kevin Montrose
Author by

Kevin Montrose

Stack Overflow Valued Associate #00004 For no good reason, I'm on twitter. I hear its compelling... somehow. I also have a blog.

Updated on February 13, 2020

Comments

  • Kevin Montrose
    Kevin Montrose about 4 years

    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.

  • Catch22
    Catch22 about 12 years
    When page A checks the origin of the message, the origin will NOT contain a trailing '/'. It does not seem to matter if page B specifies a trailing '/' or not. The other thing to note is that the URLs should be absolute URLs.
  • Jacksonkr
    Jacksonkr almost 11 years
    In a project I'm doing, I'm using file:/// Is it possible to get domain errors when pulling content solely from the local file system?
  • Greg Bogumil
    Greg Bogumil about 9 years
    This answer left me a bit confused and still searching for an answer. blog.teamtreehouse.com/cross-domain-messaging-with-postmessa‌​ge contains a very good explanation of the postMessage. What is important is that the message sender know the domain of the receiver. In the example above, A and B do not have to be the same domains, but B must know exactly what domain is used by A.
  • stackular
    stackular almost 9 years
    The question is about cross-domain. The accepted answer is about the same domain.
  • Mic
    Mic almost 9 years
    @stackular, not exactly. A and B can be any domain. That is the main reason of having postMessage
  • stackular
    stackular almost 9 years
    @Mic Yes, after reading the docs developer.mozilla.org/en-US/docs/Web/API/Window/postMessage, I saw you were correct.
  • Yash
    Yash over 8 years
    var targetOriginurl = window.document.referrer; top.postMessage('Message', targetOriginurl+'/A'); to complete my work, for IE used attachEvent() and to get domain refered these links
  • rahmatns
    rahmatns almost 5 years
    +1. We want to confirm that this solution worked on our case. We have a page that contains an iframe from different domain. Please be note that this only work in Chrome browser, as in firefox we need to use window.parent.postMessage instead of top. Though we don't know if this can be applied to any other browser.