0

I need to test out a situation where I have a parent window hosting an iframe which will be empty. I need to use the iframe as a proxy between the parent and a cross-domain resource. I've created a simple jsfiddle that should attempt to post a message from the parent to the child iframe.

What I try to do in the parent's javascript is have a handler for the child iframe, but for the life of me I cannot figure out the syntax to get it working correctly. I have tried using an addEvent helper to get the event properly added (for IE and everybody else) from examples I've seen in Modern Javascript Develop and Design:

addEvent: function(obj, type, fn) {
    if (obj && obj.addEventListener) {
        obj.addEventListener(type, fn, false);
    } else if (obj && obj.attachEvent) {
        obj.attachEvent('on' + type, fn);
    }
}

The way I'm currently trying to setup the handler for onmessage is as follows:

document.getElementById("frame1").onmessage = function(e) {
    alert(e.data);
};

I have also thought that maybe I need to be accessing the element's contentWindow, but onmessage does not seem to exist.

Is there a property or way to access an iframe such that it appears like a window and would have an onmessage that could be handled?

Update

I can see the value of onmessage set to a function and even alert(...) out the value to see that it is indeed my intended function, but I do not see it called when postMessage is called on the child iframe.

Community
  • 1
  • 1
ShelbyZ
  • 1,494
  • 1
  • 14
  • 32

1 Answers1

1

Your implementation of postMessage is incorrect. The onmessage event has to be bound to the the frame's window. Since the frame's content is from a different origin, this can only be done at the frame's side. You cannot bind this event from your page, due to the Same origin policy.

This code will work, provided that the Same origin policy is not in affect:

// Bind event to the frame's  window  object
var frame1_window = document.getElementById("frame1").contentWindow;
frame1_window.onmessage = function(e) {
    alert(e.data);
};
frame1_window.postMessage("Hello from same domain", "http://yourdomainhere.com");

Example (domain: jsfiddle.net): http://jsfiddle.net/zTctZ/3/show/
Example (domain: fiddle.jshell.net): http://jsfiddle.net/zTctZ/4/

Rob W
  • 341,306
  • 83
  • 791
  • 678
  • Attempting to set the onmessage property by document.getElementById(...).contentWindow for the iframe never returns from my js debugging. I do not see the same issue when I try to set it on document.getElementById(...). – ShelbyZ Apr 26 '12 at 18:37
  • @ShelbyZ I've included two demos in my answer, which show the alert. I've also corrected a typo: `vat` had to be `var`. – Rob W Apr 26 '12 at 18:42
  • So it seems impossible with just 1 parent window and 1 iframe not on the same domain to actually handle the child's onmessage because it would violate the same origin policy. At this point it would require the iframe to include another frame whose domain is the same as the top level parent to work it seems. – ShelbyZ Apr 26 '12 at 19:58
  • @ShelbyZ It **is** possible. A prerequisite is that the `onmessage` event is defined at the frame's side. An example of a successful application of cross-origin `postMessage` is the chromeless [YouTube ](http://stackoverflow.com/a/7513356/938089?youtube-iframe-api-how-do-i-control-a-iframe-player-thats-already-in-the-html) player, in a iframe. – Rob W Apr 26 '12 at 20:21
  • I feel like what I was trying to accomplish is a large hack and maybe I do not understand what problem I'm trying to solve on my side of things. I have actually experimented with defining the message on the frame's side and it works very well. I'm not certain how much luxury I will have with that. – ShelbyZ Apr 26 '12 at 20:41