Communicate from parent page to iFrame

Hi,

I’m working on a basic prototype that involves having a PlayCanvas app loaded into an iframe, and all the controls for the app are on the parent page. The parent page and the PlayCanvas app will almost definitely be hosted on separate servers (I have no say in this), so I’ve been looking into postMessage.

None of my tests seemed to work so I’ve gone back to the basics with this example:
https://developer.playcanvas.com/en/user-manual/publishing/web/communicating-webpage/

I don’t seem to be getting any communication from my page to the iframe though, based on what I’m seeing in the console.

I’ve set up the HTML portion here:

https://www.ripcorddev.com/iframe/iframe.html

<iframe id="app-frame" src="https://playcanv.as/e/p/JF3WFQ8W/" height="100%" width="100%" title="Iframe Example">
     <script>
          var iframe = document.getElementById("app-frame");
          iframe.contentWindow.postMessage({
          score: 10,
     }, "https://playcanv.as");
</script>

And my public project is here:
https://playcanvas.com/editor/scene/1086454

I’ve got a feeling I’m missing something simple, but at this point I’ve spent hours on this and I figured it was time to ask for help :smiley:

Ultimately what I’m looking for is a way to have an external HTML / Javascript interface that communicates to the content inside my PlayCanvas app. At some point I’ll probably need the app to talk back to the HTML but that’s further down the road.

Any help would be greatly appreciated, thank you!

For the communication between different windows, postmessage is surely a better solution than anything. I was trying the same thing from the iframe but id didn’t seem to work. So, i changed things by first i sent a message from playcanvas like this so that my window may know that playcanvas build is loaded:
window.top.postMessage("Playcanvas_Ready", "*");

And received it on the other window i.e iframe with the following function:

window.addEventListener('message', function(event) {
           // debugger;
            //alert(`Received ${event.data} from ${event.origin}`);
  // line 2  
        document.getElementById('playcanvasInput').contentWindow.postMessage('hello','https://playcanv.as');


            if(source ==null)
            {

               source=event.source;
               origin= event.origin;
            }
            //event.source.postMessage('Message received', event.origin);
            
         });

At line 2, i sent back the message to the playcanvas and here is how I receive it in playcanvas and it worked well. Remember the following code was outside of any function i.e initilize/update etc

function displayMessage (evt) {
    var message;
  

    console.log(evt);
    if (evt.origin !== "https://robertnyman.com") 
    {

        message = "You are not worthy";

    }
    else {

        message = "I got " + evt.data + " from " + evt.origin;

    }
    //document.getElementById("received-message").innerHTML = message;


}
if (window.addEventListener) {
    // For standards-compliant web browsers
    window.addEventListener("message", displayMessage, false);

}
else {
    window.attachEvent("onmessage", displayMessage);

}
1 Like

Also bare in mind that the publish link for PlayCanvas is already in an iframe.

To use the iframeless version, add a /e before the /p in the URL

3 Likes

Thanks for the help guys! I think I’ve got it figured out now.

@saif’s example helped me clear up what I was trying to do. :+1:

Part of the problem looks like a Chrome extension I was using would spam about a dozen events when the page loaded which was making me think a lot more was actually happening than what should have been. :frowning:

I need to clean up a couple things then I’ll post the finished code in case someone else stumbles on this thread.

3 Likes