How to properly use postMessage to do cross-domain messaging with html5 and modern browsers ? I still get errors

20,988

I've just tried your code and this seems to work in Chrome. It uses jsfiddle and jsbin to pass messages between parent and child windows.

http://jsbin.com/oxesef/4/edit#preview

Share:
20,988

Related videos on Youtube

João Pinto Jerónimo
Author by

João Pinto Jerónimo

Updated on September 21, 2020

Comments

  • João Pinto Jerónimo
    João Pinto Jerónimo about 3 years

    I'm sure something is wrong here but I can't quite put a finger on it... The example here behaves just fine with no notices or errors on the console, so it means my browser supports cross domain messaging with html5 (of course it does, it's Chrome 14..).

    My code does more or less the following: A script loaded in WebsiteA.com created an iframe and appends it to WebsiteA.com's document. The frame appended will contain WebsiteB.com and when it's loaded, it must send a message to it's parent, WebsiteA.com, to tell it that WebsiteB.com is ready to receive some JSON. When WebsiteA.com get's this message, it sends back the JSON.

    So WebsiteA.com has a line just before </body> just like this: <script scr="http://WebsiteB.com/load-my-iframe.js" type="text/javascript"></script>, and inside the load-my-iframe.js, I have the following:

    var child = document.createElement('iframe');
    child.src = 'http://WebsiteB.com/child.html';
    
    var body = document.getElementsByTagName('body')[0]
    body.appendChild(child);
    
    var SomeJSON = {"something" : "that WebsiteB should have"};
    
    window.onmessage = function (e) {
        if (e.origin === 'http://WebsiteB.com' && e.data === 'ready') {
                e.source.postMessage(SomeJSON, 'http://WebsiteB.com');
        }
    }
    

    So that creates the iframe element, appends it to WebsiteA.com's document and waits for it to say it's ready (I guess...). On WebsiteB.com, I have the file child.html that is src of the iframe loaded in WebsiteA.com's document, and that file has the following:

    <!DOCTYPE html>
    <html lang="pt">
        <head>
            <title>WebsiteB.com</title>
            <script type="text/javascript">
                window.onload = function () {
                    window.parent.postMessage('ready','*');
                }
    
                window.addEventListener('message', receiveMessage, false);
                function receiveMessage(event) {
                    if (event.data.something === "that WebsiteB should have") {
                        document.write('It worked!');
                    }
                }
            </script>
        </head>
        <body>
        </body>
    </html>
    

    And now the weird stuff:

    Sadly I do not own WebsiteA.com and WebsiteB.com, but I managed to have this working between one top level domain and a subdomain (that ends with .no.de). It really does work, BUT in Google Chrome 14's console I get the classic Unsafe JavaScript attempt to access frame with URL http://WebsiteA.com/ from frame with URL http://WebsiteB.com/child.html. Domains, protocols and ports must match.. The example from html5demos works just fine without this error.

    Why do I get this error and how do I get rid of it ?

    • Alan H.
      Alan H. almost 11 years
      Are you sure it is not working? I saw this and I got a warning, but it worked, I believe.
  • João Pinto Jerónimo
    João Pinto Jerónimo about 12 years
    I thought about that, but Porthole (github.com/ternarylabs/porthole) seems better designed, simpler, smaller (5kb minified) and supports vintage browsers. But for what I'm doing I need only browsers that support html5 so everything that is backwards compatible is not needed and overweight.