0

I'm working with 2 localdomains, localhost and domain1 to test a postMessaging system using iFrames from both domains.

I can correctly identify the respective window element (on both domains) to send message to and receive replies. My problem is, that the 2nd parameter sent in my postMessage (the URL I'm sending the message from) is not accepted by the listener on the respective other domain. Only if I declare the sender to be "*", my messaging works.

This does not work sending a message to the foreign domain:

 // targetWindow = window of foreign domain
 targetWindow.postMessage({
    "foo": "bar"
  }, window.location.href);

This works:

 // targetWindow = window of foreign domain
 targetWindow.postMessage({
    "foo": "bar"
  }, "*");

Same for replies back to the sending domain (using window.top). This does not work:

 window.top.postMessage({
  "baz": "bam"
}, window.location.href.split("?")[0]);

while this does:

window.top.postMessage({
  "baz": "bam"
}, "*");

Question:
Why is this so? I thought I had to supply the sending-url as 2nd parameter to enable authentication. If so, why do my events not trigger? Is the reason me working on localhost/domain1?

Thanks for help!

frequent
  • 27,643
  • 59
  • 181
  • 333
  • If they're on different domains, why would you expect `window.location.href` to match on the other domain? – Ian Jun 03 '13 at 14:11
  • it should not match (I guess). I thought the 2nd parameter should be the URL the postMessage is being sent from, so that the receiving window can authenticate the sender. If I log the `window.location.href...` it correctly returns `http://domain1/foo/some/file.html` which I wanted to pass along with the postMessage, so I can verify it. But when doing so, the postMessage is never sent without any errors popping up. Only when I use `"*"` it works. – frequent Jun 03 '13 at 14:51
  • i thought you pass a domain, not a path... – dandavis Jun 03 '13 at 14:52
  • is it? [Mozilla's `targetOrigin`](https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage) says it should be a URI, which is... – frequent Jun 03 '13 at 14:53
  • @frequent Then you should read more about it: https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage#Syntax . The second parameter's is for you to specify what domain/port you want the message to be broadcast to – Ian Jun 03 '13 at 14:53
  • @Ian: thanks. Still confused. I thought that would be set by specifying `otherWindow`? Reading now (for the nth time...) then posting back. Thanks so far. – frequent Jun 03 '13 at 14:57
  • @frequent That's funny you say that - I was reading over those docs the other day and was thinking the same thing. Since I don't use `window.postMessage`, I didn't care to try to figure it out more. I think if you specify `window` for `otherWindow`, it broadcasts (because you normally don't have a reference to another window). Either way, you can specify `targetOrigin` to make sure the target's scheme/domain/port match something specific. So again, if `otherWindow` references a different domain, you can't just use `window.location.href` for `targetOrigin`. Does that make more sense? – Ian Jun 03 '13 at 15:02
  • yes. it's working now. Thanks. I think the term `targetOrigin` is ambiguous, because it can be understood as `target` or `origin`. Make your tips an answer so I can check? – frequent Jun 03 '13 at 15:07
  • Couldn't agree more with that, very confusing. – godhar Aug 25 '23 at 10:02

1 Answers1

2

The second pram is targetOrigin, this is a security restriction to stop your message being intercepted. It should be set to the domain of the window the message is being sent to rather than the one it is coming from.

Here's an example using an iframe to set the second field, that takes the src value from the iFrame and chops it down to being protocol + domain + port. Which is what is required to set target origin.

var target = iframe.src.split('/').slice(0,3).join('/');
iframe.contentWindow.postMessage('foo', target);
David Bradshaw
  • 11,859
  • 3
  • 41
  • 70