17

I'm trying to send a simple message from a child document (an iframe) back to its direct parent using the window.postMessage API.

Within the parent document I have the following:

window.addEventListener("message", receiveMessage, true);
var receiveMessage = function(event) {
    console.log("Recieved event " + JSON.stringify(event));
}

Then, in the iframe I have the following:

window.parent.postMessage('message', '*');

Based on everything I've read, this should work and my log message should be written to the console. Except it's not working.

I'm aware that using the * as the targetOrigin is not always secure, but at this point I just want to sort out the linkage.

Any ideas or anything obvious that I'm missing?

chris.wilkinson
  • 171
  • 1
  • 1
  • 3
  • What does "not working" mean in this context? Are there any errors messages you get? – Frxstrem Oct 02 '16 at 22:09
  • 1
    Is there a `message` event handler at `iframe` element? Is `postMessage()` called at `parent` window? – guest271314 Oct 02 '16 at 22:24
  • If you really wrote what is in your question, `receiveMessage` is still undefined when you attach it as your event handler. Declare it before hand or use the `function receiveMessage(){}` notation so that it gets defined at top of the script. – Kaiido Oct 02 '16 at 23:56
  • @Kaiido I edited my script and defined the receiveMessage function up-stream. The message still doesn't get routed from my iframe. Interestingly enough, I also have an FB connect library running on the page from inside the same iframe and it is sending a message to the parent. – chris.wilkinson Oct 03 '16 at 20:29
  • @guest271314 I don't think I need to define a 'message' event handled inside the iframe. From what I understand, I just need a handle to the parent window, which I have with the global window.parent variable, then I simply need to call postMessage(). I might be wrong though, since my code isn't working. – chris.wilkinson Oct 03 '16 at 20:34
  • @Frxstrem - By 'not working' I mean that the message being sent from the iframe is not getting to the parent and the parent isn't writing to the console. There are no error messages, the call to window.parent.postMessage() from inside the iframe is simply not doing anything. – chris.wilkinson Oct 03 '16 at 20:36
  • @chris.wilkinson _"I don't think I need to define a 'message' event handled inside the iframe."_ When is `postMessage` called within `iframe`? Can you create a plnkr https://plnkr.co to demonstrate what you have tried? See also [How to clear the contents of an iFrame from another iFrame](http://stackoverflow.com/questions/33645685/how-to-clear-the-contents-of-an-iframe-from-another-iframe) . – guest271314 Oct 03 '16 at 23:05
  • I agree with the plnkr request. Also, what you want to read is event.data, and normally you don't need to JSON.whatever. Also, try your setup in a minimal version, include only parent script and iframe, and show us how you did "*defined the receiveMessage function up-stream*" in an [edit] to your question, because it is the main typo still in here. – Kaiido Oct 04 '16 at 00:39

2 Answers2

5

I've had exactly the same problem and have solved it by moving the "script" section above the iframe declaration. Here is the final code of the parent site :

<script>
    window.addEventListener('message', e => {
        console.log(e.data);

        if (e.origin == "http://localhost:8080"
            && e.data == "CallFunctionA") {
            FunctionA();
        }
    }, false);

    function FunctionA() {
        window.alert('FunctionA called')
    }
</script>

<html>

<body>
    <h1>Hello static web site !!!!</h1>

    <iframe name="ifu-frame" src="http://localhost:8080/index.html" />
</body>

</html>

And the content of the iframe is simply :

<button onclick="window.parent.postMessage('CallFunctionA', 'http://localhost:8081')">Call function A</button>

If I put the "script" section at the bottom of the document then it doesn't work anymore...

bN_
  • 534
  • 10
  • 14
3

Ensure your callback function receiveMessage() is declared before passing it into the addEventListener method.

Here is your revised parent script:

var receiveMessage = function(event) {
    console.log("Recieved event " + JSON.stringify(event));
}
window.addEventListener("message", receiveMessage, true);
James Lawruk
  • 26,651
  • 19
  • 117
  • 128