Kiran
Kiran

Reputation: 481

HTML5 postMessage returns undefined

I am trying to do cross-domain communication using postMessage between a page (on example1.com) and an iframe on the same page that is on example2.com

When the iframe is done loading, it sends a postMessage to the parent page using the following command:

parent.postMessage('hello parent', 'http://example1.com'); //this command works

In the event handler for postMessage in the parent page (on example1.com), I send a response back to the child page (example2.com) using the following function:

//this function is defined in example1.com:

function receiveMessage(event){

    if (event.origin == "http://example2.com"){

        console.log('Message Received from iframe'); //this line works

        event.source.postMessage('hello to you too', event.origin); //this line does not work

    }

}

For some reason, the event handler for postMessage in the iframe is not triggered.

//this function is defined in example2.com

function receiveMessage(event){

    if (event.origin == "http://example1.com"){ // I even tried removing this check to no avail

        console.log('Message Received from parent'); //this line works

    }

}

When the parent tries to send a message to the iframe it simply returns undefined.

Any help is appreciated!

EDIT:

I tried changing the following line in example1.com's receiveMessage event:

event.source.postMessage('hello to you too', event.origin);

to this:

event.source.postMessage('hello to you too', 'http://example2.com');

But I get this following error:

Unable to post message to http://example2.com. Recipient has origin http://example1.com

Why is event.origin evaluating to http://example1.com when it is receiving a message from example2.com?

example1.com is trying to send itself a postMessage. This ought to be the source of the error

Upvotes: 2

Views: 7598

Answers (2)

Mahdi Arjangi
Mahdi Arjangi

Reputation: 41

In my Vue project, i got same result as you, and finally i changed my origins to another host like 127.0.0.10 and then i got data object

here is my code

first origin : 127.0.0.10:8000

function sendMessage() {
  document
    .getElementById('frame')
    .contentWindow
    .postMessage('Hello world!', '*');
}
<iframe class="d-none" src="http://127.0.0.20:8080/login" onload="sendMessage()" id="frame"></iframe>

second origin : 127.0.0.10:8000

window.addEventListener(
  "message",
  function (event) {
      if (event.origin.indexOf('127.0.0.10:8000') > 0)
      {
          console.log(event.data);
      }
  }
);

Upvotes: 0

Elger van Boxtel
Elger van Boxtel

Reputation: 1060

Sometimes postMessage can be very unclear in which frame sends and which one receives. For this reason I created a little script to help unravel communication between frames.

Add the following snippet to your page and watch your console to see what happens. Make sure you add it to your page before the inter frame communication with postMessage begins.

  var listener = function (e) {
    console.log('Caught ', e.type, ' event from ', e.source.self, ' to ', e.target, ' origin ', e.origin, ' with data ', e.data, '. Full details: ', e);
  };

  function addToFrame(el) {
    var frames = el.querySelectorAll('iframe'), ifrm = 0;
    for (var i = 0; i < frames.length; i++) {
      frames[i].contentWindow.addEventListener("message", listener, true);
      ifrm += addToFrame(frames[i].contentWindow.document);
    }
    return i + ifrm;
  }

  window.addEventListener("message", listener, true);
  var c = addToFrame(document);
  console.log('Recursively added listener to main window and', c, 'frames');

In your console it clearly states which frame sends what to which other frame. For more details, please see my blog post I've prepared for you on my site.

I hope this will help figuring out the iframe communication ;-)

p.s. If this does not help, please create a jsfiddle of your problem. This will make it easier for us to understand the problem you're having...

Upvotes: 3

Related Questions