[Webkit-unassigned] [Bug 258674] New: BroadcastChannel inside cross-origin iframe doesn't work

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Thu Jun 29 08:17:46 PDT 2023


https://bugs.webkit.org/show_bug.cgi?id=258674

            Bug ID: 258674
           Summary: BroadcastChannel inside cross-origin iframe doesn't
                    work
           Product: WebKit
           Version: Safari 16
          Hardware: Unspecified
                OS: Unspecified
            Status: NEW
          Severity: Normal
          Priority: P2
         Component: WebKit API
          Assignee: webkit-unassigned at lists.webkit.org
          Reporter: saddy802 at gmail.com

Steps to reproduce:

I have two sites with different origins. Let it be foo.com and bar.com. Site foo.com fires messages through BroadcastChannel with 'payment-info' name. I also have an iframe, hosted on foo.com which is built in bar.com. Here's iframe code:

<html><head><script type="text/javascript">
(function () {
const bc = new BroadcastChannel('payment-info');

    bc.addEventListener('message', (m) => {
        const data = JSON.parse(m.data);
        data.channel = 'payment-info';

        if (window.top !== window) {
            window.top.postMessage(JSON.stringify(data), '*');
        }
    });
})();
</script></head><body></body></html>
So iframe subscribes to 'payment-info' broadcast channel and when it fires, iframe post a message to it's parent window aka bar.com with some information.

On bar.com side I just listen to 'message' event and call 'receiveMessage' function with JSON.parse

window.addEventListener('message', function (message) {
receiveMessage(message);
});

It's expected to work on my site bar.com in all browsers. It doesn't work in Safari and Firefox but works in Chrome.


I combined code from several files of index.html, index2.html and iframe.html which I used to test it locally. index.html and iframe.html are considered to be from one origin and index2.html is from another. Unfortunately it's impossible to test it just as plain HTML/JS without two different servers with different domains

<!--INDEX CODE-->
<!doctype html>
<html lang="">

<head>
  <meta charset="utf-8">
  <title></title>
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <meta property="og:title" content="">
  <meta property="og:type" content="">
  <meta property="og:url" content="">
  <meta property="og:image" content="">

  <meta name="theme-color" content="#fafafa">
</head>

<body>
<p>index page</p>
<a href="/page.html">link</a>

<script>
  let i = 0;
  const bc = new BroadcastChannel('payment-page');

  function sendItem() {
    i+=1;

    const message = '{"message":"Hello from the new window!"}';
    if (window.opener) window.opener.postMessage(message, '*');

    const data = { message: `Hello from broadcast ${i}` };
    console.log(JSON.stringify(data));

    bc.postMessage(JSON.stringify(data))

    console.log(message)
  }
</script>



<button onclick="sendItem()">send item</button>
</body>

</html>
<!--END OF INDEX CODE-->

<!--IFRAME CODE-->
<html><head><script type="text/javascript">
  (function () {
    const bc = new BroadcastChannel('payment-page');

    console.log('broadcast channel is created', bc)

    bc.addEventListener('message', (m) => {
      console.log('proxy: receive message ', m);

      const data = JSON.parse(m.data);
      data.channel = 'payment-page';

      if (window.top !== window) {
        // Inside iframe. Proxy to top.
        console.log('proxy: send to parent');

        window.top.postMessage(JSON.stringify(data), '*');
      }
    });
  })();
</script></head><body></body></html>

<!--END OF IFRAME-->

<!--INDEX2 CODE-->
<!doctype html>
<html class="no-js" lang="">

<head>
  <meta charset="utf-8">
  <title></title>
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>

  <iframe
          width="100"
          height="100"
          src="http://domain-1.com:3000//iframe.html"
  ></iframe>

  <script>
   window.addEventListener('message', function (message) {
      if (message.data && typeof message.data === 'string') {
        console.log(JSON.parse(message.data))
      }
    });
  </script>
</body>

</html>
<!--END OF INDEX2 CODE-->

-- 
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-unassigned/attachments/20230629/006b9683/attachment.htm>


More information about the webkit-unassigned mailing list