How can I post a message to an iframe loaded later without violating CORS policies?

I need to send a message to an iframe that is loaded after a user clicks a link.

The nature of the error message makes me believe that this is Javascript that is angry and not nginx. It seems like it didn’t even attempt the postMessage.

javascript console

(index):6 loading site2 iframe ...
(index):8 sending message from site1 to site2 ...
(index):9 Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('http://site2.example.com') does not match the recipient window's origin ('http://site1.example.com').

site1.example.com/index.html

<html>
<head>
<script type="text/javascript">

    function loadIFrame() {
        console.log( "loading site2 iframe ..." );
        document.getElementById('myiframe').src = "http://site2.example.com";
        console.log( "sending message from site1 to site2 ..." );
        document.getElementById('myiframe').contentWindow.postMessage( "Hello World!", 'http://site2.example.com');
    }

</script>
</head>
<body>
    <h2>Site1</h2>

    <a href="#" onclick="loadIFrame()">load iframe</a>
    <br/><br/><br/>

    <iframe id="myiframe" style="width:600px; height: 400ps;"></iframe>

</body>
</html>

site2.example.com/index.html

<html>
<head>
<script type="text/javascript">
  window.addEventListener( 'message', event => {
    if ( event.origin === 'http://site1.example.com' ) {
      const item = event.data;
      console.log( "site2 received message: " + item );
    }
  });
</script>
</head>
<body>
<h2>Site2</h2>

<body>
</html>

site1.example.com nginx config

server {
    listen 80;
    server_name site1.example.com;

    location / {
        root /home/user/test-sites/site1;

    }
}

site2.example.com nginx config

server {
    listen 80;
    server_name site2.example.com;

    set $cors "";
    if ($http_origin ~* (.*.example.com)) {
        set $cors "true";
    }

    location / {
        root /home/user/test-sites/site2;

        if ($cors = "true") {
            add_header 'Access-Control-Allow-Origin' "$http_origin" always;
            add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
            add_header 'Access-Control-Allow-Credentials' 'true' always;
            add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always;
        }

        if ($request_method = OPTIONS) {
            add_header 'Access-Control-Max-Age' 1728000;
            add_header 'Content-Type' 'text/plain charset=UTF-8';
            add_header 'Content-Length' 0;
            return 204;
        }
    }
}

I should also mention that this header shows up in site2.example.com within the iframe

Referrer Policy:
strict-origin-when-cross-origin

I’m not sure if that should be different given my attempted configuration.