Search code examples
javascripthtmlreactjsiframepostmessage

Iframe CDN not responding to postMessage()


I have a iFrame which has CDN source. but CDN'S html is not responding to postMessage API of JS. As far as I know, postMessage API is suppose to work cross domain. Here is my code:

Main App:

    <iframe  ref={elemRef} style={{position: 'relative', height: '90vh', width: '100%'}} id={'myIframe'} src='http://d34gxw3jqlasaag.cloudfront.net/sampletemplate2.html' frameBorder="0"></iframe>
    
    
      const elemRef = useCallback((node) => {
        console.log("node: ", node);
        frame = document.getElementById("myIframe");
        console.log("frame: ", frame)
        if (node !== null) {
          // frame.contentWindow.postMessage({call:'sendValue', value: {task: {input: taskInput}}});
          setTimeout(() => {
           
             frame.contentWindow.postMessage({call:'sendValue', value: {task: {input: taskInput}}});
        
          

          }, 500);
      }

sampletemplate2.html

<!DOCTYPE html>
  <html>
    <head>
      <title>My first HTML document</title>
   

   <script>
   
     
     const cloudFrontUrl = 'http://localhost:3333/build';
   
     const moduleScript = document.createElement('script');
     moduleScript.setAttribute('type', 'module');
     moduleScript.setAttribute('src', `${cloudFrontUrl}/studios.esm.js`);
   
     const nomoduleScript = document.createElement('script');
     nomoduleScript.setAttribute('nomodule', '');
     nomoduleScript.setAttribute('src', `${cloudFrontUrl}/studios.js`);
   
     document.head.append(moduleScript);
     document.head.append(nomoduleScript);

     window.addEventListener('message', function(event) {
          var origin = event.origin
          // if (origin !== /*the container's domain url*/)
          //     return;
          console.log("Received event.....: ", event)
          if (typeof event.data == 'object' && event.data.call=='sendValue') {
              // Do something with event.data.value;
              console.log("task.input: ", event.data.value.task)
              const data = event.data.value.task.input


    const htmlEncodedTaskInput =  JSON.stringify(data.taskInput).replaceAll("\"","&quot;");
    console.log("data: ", data);


    console.log("htmlEncodedTaskInput: ", htmlEncodedTaskInput)
    //Load the requested template dynamically
    const template = `<task-loader domain="'beta'"
                        template-name="${data.template_name}"
                        task-input="${escape(htmlEncodedTaskInput)}"/>`

    document.getElementById("placeholder").innerHTML = template;



          }
      }, false);
    
   </script>
   
   <div id="placeholder"></div>
 
   

</head>
</html>

It's worth to note that if I put the file sampletemplate2.html inside main window's sub folder, it responses fine. But it doesn't respond when I try through CDN


Solution

  • Although postMessage works cross-domain, you must in that case specify the second parameter (targetOrigin), which, in this case, seem to be http://d34gxw3jqlasaag.cloudfront.net.