9

I'm having an issue communicating from my parent window to the child iFrame. But in the other side, everything works perfectly. Here is how I get the chil iFrame object in order to fire the postMessage function:

var iFrame = document.getElementById('Frame').contentWindow;

When I print it int he console, I get the following:

Window {parent: Window, opener: null, top: Window, length: 0, frames: Window…}

When I proceed to the postMessage function as follows:

iFrame.postMessage("message", "http://contoso.com");

It shows me an error when loading the page: iFrame.postMessage is not a function. When I execute the postMessage in console, I get an undefined

What am I doing wrong ?

Hubert Solecki
  • 2,611
  • 5
  • 31
  • 63
  • You still need to have control of both websites. Do you own `contoso.com`? – zer00ne Dec 06 '16 at 09:20
  • You need to setup e.origin on `contoso.com`, are you sure you are able to edit that site? Last time I checked, MS still owned it. – zer00ne Dec 06 '16 at 09:30
  • I've replaced my website by contoso.com just for the post. In the event listener in the child iFrame, the e.origin is set correctly. I've added log just before manipulating the event object but it never gets to that point. – Hubert Solecki Dec 06 '16 at 09:35
  • Maybe this answer might help. – zer00ne Dec 06 '16 at 09:44

3 Answers3

13

try this

var iFrame = document.getElementById('Frame');
iFrame.contentWindow.postMessage("message", "http://contoso.com");

I had this problem too. I found solution from this website https://www.viget.com/articles/using-javascript-postmessage-to-talk-to-iframes

eknimation
  • 139
  • 2
  • 5
  • 1
    Error: `Failed to execute 'postMessage' on 'DOMWindow': The target origin provided does not match the recipient window's origin.` It works from child element to parent but not the way around. – temo Oct 12 '18 at 11:33
  • 1
    @temo I was able to get it working cross domain, see my answer below. – Djave Aug 27 '21 at 13:22
  • the below solution from @Djave works, we need to store the source in the parents addEventListener (in some variable or in an array if your use case involves multiple child iframe communication) when the child iframe does a postMessage to the parent for the first time. This source can then be used to communicate from parent to child. – Arif Jan 11 '23 at 12:32
8

I wasn't able to get this working using a querySelector approach.

What worked for me was the following. I'll refer to the two webpages as the parent that has an iframe on it and the src as the page inside the iframe.

On the src page, I post a message, with the parent url as the origin:

// src
window.parent.postMessage({
  type: "connect",
  url: window.location.href
}, "http://iframeparent.dev", );

Then in the parent page, I listen for this. It will have a property called source which is the iframe in question. This property can be posted to.

// parent
window.addEventListener("message", (event) => {
  // this is the magic connection:
  event.source; 
}, false);

So you could do something like:

// parent
let sources = [];

window.addEventListener("message", (event) => {
  sources.push(event.source);
}, false);

function something() {
  sources.forEach(source => {
    source.postMessage({some: "data"}, "http://iframesrc.dev")
  })
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
Djave
  • 8,595
  • 8
  • 70
  • 124
2

Below code also works.

$('#id')[0].contentWindow.postMessage("hello world",targetOrigin);

There is a difference between jQuery selector and document.getElementById.

Document.getElementByID returns HTML DOM object.
jQuery selector returns jQuery object.

For more information please find below link. document.getElementById vs jQuery $()

Mathi kumar
  • 373
  • 1
  • 4
  • 10