Avenues_Q
Avenues_Q

Reputation: 55

postMessage not working from parent to iframe

I am trying to send a cookie from my parent page to an iframe.

Here is my postMessage code:

<script>
  try {
    var postObject = JSON.stringify({
      event: 'DOMPageLoad',
      data: '{{Page URL}}'
    });
    parent.postMessage(postObject, 'https://mysite/l/839063/2020-02-26/29bh');
  } catch(e) {
    window.console && window.console.log(e);
  }
  </script>

I've tried using this from the iframe to the parent and it works like a charm, but I can't get it to work the other way around.

Here is my eventListener code:

<script type="text/javascript">
(function(window) {

    addEvent(window, 'message', function(message) {
      try{
      var data = JSON.parse(message.data);
      var dataLayer = window.dataLayer || (window.dataLayer = []);
      if (data.event) {
        dataLayer.push({
          'event': data.event,
          'postMessageData': data
        });
      }
      }catch(e){}
    });

    // Cross-browser event listener
    function addEvent(el, evt, fn) {
      if (el.addEventListener) {
        el.addEventListener(evt, fn);
      } else if (el.attachEvent) {
        el.attachEvent('on' + evt, function(evt) {
          fn.call(el, evt);
        });
      } else if (typeof el['on' + evt] === 'undefined' || el['on' + evt] === null) {
        el['on' + evt] = function(evt) {
          fn.call(el, evt);
        };
      }
    }

  })(window);
</script>

My assumption is that the issue has to do with how I am trying to send the message to the iframe. Right now I am using parent.postMessage, but I assume it will need to be something different for the iframe.

enter image description here

This is probably something really simple, but I am quite new to javascript and simply don't know what I don't know.

Upvotes: 0

Views: 3135

Answers (2)

santhosh srinivasan
santhosh srinivasan

Reputation: 419

I was using Chrome to check the console.log output from the parent window being sent to the child iframe, but I noticed that Chrome hides these logs by default. To view them, you need to open the developer tools and select the dropdown which says 'top' and change it to your iframe.

Upvotes: 0

Ben Larson
Ben Larson

Reputation: 475

I think you're right about the problem being parent.postMessage. The parent property references the parent of the current frame, but here you want to post a message to a child frame.

To access the window of your iframe, you'll first need to get the iframe somehow. For example, if your iframe has id="my-iframe", you can use this:

var myIframe = document.getElementById('my-iframe');

Then you can access the iframe's window using the contentWindow property:

myIframe.contentWindow.postMessage...

That should do it!

P.S. I see you have data: '{{Page URL}}' with quotes, but I don't think you need them. You should just be able to use data: {{Page URL}} if I'm not mistaken.


Edit: Picking the right way to trigger the code

Connecting this code to the All Pages trigger in GTM will probably cause issues, because the iframe hasn't necessarily loaded by the time that trigger fires. I think these are your two best options:

  • Waiting for the iframe to tell you it's ready (probably the best option)
    You could add some code to the iframe that posts a message to the parent as soon as it loads. When the parent receives the message it can send its message to the iframe, and be sure the iframe is ready for it.
  • Using GTM's Window Loaded trigger type (easy fix, but not great)
    When you create a GTM trigger you will see the Window Loaded trigger type. This will only fire once everything on the page has loaded, including any iframes. If you have any large images or anything though, the Window Loaded event could fire way after your iframe is ready, which is just a waste of time.

Upvotes: 1

Related Questions