首页 > 解决方案 > postMessage 无法从父级到 iframe

问题描述

我正在尝试将 cookie 从我的父页面发送到 iframe。

这是我的 postMessage 代码:

<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>

我试过从 iframe 到父级使用它,它就像一个魅力,但我不能让它反过来工作。

这是我的事件监听器代码:

<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>

我的假设是这个问题与我尝试将消息发送到 iframe 的方式有关。现在我正在使用parent.postMessage,但我认为 iframe 需要有所不同。

在此处输入图像描述

这可能是非常简单的事情,但我对 javascript 很陌生,根本不知道我不知道什么。

标签: javascriptcookiesiframegoogle-tag-manager

解决方案


我认为你对问题的看法是正确的parent.postMessage。该parent属性引用了当前框架的父框架,但在这里您要向子框架发布消息。

要访问您的窗口,iframe您首先需要以iframe某种方式获取。例如,如果你iframeid="my-iframe",你可以使用这个:

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

然后您可以使用contentWindow属性访问iframe's 窗口:

myIframe.contentWindow.postMessage...

应该这样做!

PS我看到你有data: '{{Page URL}}'引号,但我认为你不需要它们。data: {{Page URL}}如果我没记错的话,你应该可以使用。


编辑:选择正确的方式来触发代码

将此代码连接到All PagesGTM 中的触发器可能会导致问题,因为在iframe触发器触发时不一定会加载。我认为这是您最好的两个选择:

  • 等待iframe告诉你它已经准备好了(可能是最好的选择)
    你可以添加一些代码到iframe它加载后立即向父级发布消息。当父母收到消息时,它可以将消息发送到iframe,并确保iframe准备好接收它。
  • 使用 GTM 的Window Loaded触发器类型(容易修复,但不是很好)
    创建 GTM 触发器时,您将看到Window Loaded触发器类型。这只会在页面上的所有内容都加载后触发,包括任何iframes. 但是,如果您有任何大图像或任何东西,则该Window Loaded事件可能会在您iframe准备好后立即触发,这只是浪费时间。

推荐阅读