Wednesday, June 5, 2024
 Popular · Latest · Hot · Upcoming
177
rated 0 times [  183] [ 6]  / answers: 1 / hits: 40058  / 12 Years ago, fri, september 28, 2012, 12:00:00

I have been stuck on this for hours.



I have a.html on http://example.com that contains an iframe with src to
b.html on http://subdomain.example.com. a.html has some JS code
to postMessage to the iframe.



The code to postMessage is simple:



iframe_window.postMessage('message', iframe_element.src)


But this way, Chrome throws an error:



Unable to post message to http://subdomain.example.com. Recipient has origin null.


I have also tried:



iframe_window.postMessage('message', 'http://subdomain.example.com')


But NO LUCK!



This is the ONLY WAY it works:



iframe_window.postMessage('message', '*')


But I have heard '*' is not good to use.



No problems in Firefox.


More From » jquery

 Answers
3

It looks like this might be an issue with the child iframe not being loaded at the time the signal is sent, thus iframe.src doesn't have the proper value.



I did some testing and got the same error as you, but when I wrapped the postMessage call in a setTimeout and waited 100ms then there was no error, which tells me that this is an initialisation race condition.



Here's how I implemented a cleaner solution without the setTimeout:



Parent:



window.addEventListener(DOMContentLoaded, function() {

var iframe = document.querySelector(iframe)
, _window = iframe.contentWindow

window.addEventListener(message, function(e) {

// wait for child to signal that it's loaded.
if ( e.data === loaded && e.origin === iframe.src.split(/).splice(0, 3).join(/)) {

// send the child a message.
_window.postMessage(Test, iframe.src)
}
})

}, false)


Child:



window.addEventListener(DOMContentLoaded, function() {

// signal the parent that we're loaded.
window.parent.postMessage(loaded, *)

// listen for messages from the parent.
window.addEventListener(message, function(e) {

var message = document.createElement(h1)

message.innerHTML = e.data

document.body.appendChild(message)

}, false)

}, false)


This is a simple solution in which the child will signal to anyone that it's loaded (using *, which is okay, because nothing sensitive is being sent.) The parent listens for a loaded event and checks that it's the child that it's interested in that's emitting it.



The parent then sends a message to the child, which is ready to receive it. When the child gets the message it puts the data in an <h1> and appends that to the <body>.



I tested this in Chrome with actual subdomains and this solution worked for me.


[#82854] Thursday, September 27, 2012, 12 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
ryleymarkelb

Total Points: 554
Total Questions: 106
Total Answers: 95

Location: Norway
Member since Mon, May 23, 2022
2 Years ago
;