This week I came across an annoying requirement to embed another third-party Web project in my Web project. The first thing that came to mind was to use iframe, but here’s the thing: I interact with third-party Web projects, which violates the same origin policy, and dealing with cross-domain issues is one of the biggest headaches.

The requirement is that if you click on some button on my page, it will feed back to the iframe child page in real time, and the child page will respond.

The immediate solution that came to mind was to use NGINX to broker the two projects under the same domain name. But that seems like overkill. Is there a faster and easier way?

There is a postMessage method under the Window object that is specifically used to solve cross-domain communication problems.

PostMessage can be used to communicate with iframe across domains. PostMessage can be used to communicate with iframe across domains. PostMessage can be used to communicate with iframe across domains.

Let’s start by simulating a scenario where we have two pages from different sources, and iframepage.html is a child of index.html:

<! -- index.html -->

<body style="border:5px solid #333;">

  <h1>this is index</h1>

  <iframe src="./iframePage.html" id='myframe'></iframe>

</body>Copy the code
<! -- iframePage -->

<body style="border:5px solid #333;">

  <h1>this is iframePage</h1>

</body>Copy the code

Now the two iframes cannot communicate because they are from different sources (assuming a cross-domain problem), which is where postMessage comes in.

Let’s first try sending a message from the parent page to the child page:

// idnex.html

// Get the iframe element
iFrame = document.getElementById('myframe')

// Send the message after the iframe is loaded. Otherwise, the sub-page will not receive the message
iFrame.onload = function(){

  // Iframe sends a message immediately after loading
  iFrame.contentWindow.postMessage('MessageFromIndex1'.The '*');

}Copy the code

PostMessage is mounted on the window object, so after iframe is loaded, use ifame. ContentWindow to get the Window object of iframe, and then call postMessage, which is equivalent to sending a message to the child page.

The first argument to the postMessage method is the data to send, which can be any primitive type of data.

Before Gecko 6.0 (Firefox 6.0 / Thunderbird 6.0 / SeaMonkey 2.3), the first argument had to be a string.

The second parameter of the postMessage method can set the URL to be sent to. If the URL of the current subpage is inconsistent with the setting, the message will fail to be sent. We set the parameter to *, indicating that all urls are allowed to be sent.

The postMessage method has a third argument, which is advanced usage and is not discussed here, but can be learned later in MDN.

The message is sent to iframepage.html and we receive the message:

// iframePage.html

// The callback function
function receiveMessageFromIndex ( event ) {
  console.log( 'receiveMessageFromIndex', event )
}

// Listen for message events
window.addEventListener("message", receiveMessageFromIndex, false);Copy the code

We just need to listen for the message event in the child page and set up the callback function, and look at the printed event:

The Data property in the Event object holds the data we passed from the parent page, and that’s it!

Let’s try sending data from child pages to parent pages again:

// iframePage.html

// Send a message to the parent page with data as the object
parent.postMessage( {msg: 'MessageFromIframePage'}, The '*');Copy the code

The parent page receives data:

//index.html

// The callback function
function receiveMessageFromIframePage (event) {
    console.log('receiveMessageFromIframePage', event)
}

// Listen for message events
window.addEventListener("message", receiveMessageFromIframePage, false);Copy the code

I can see that it is possible to transfer different data, in which case data is an object:

You can clone the code at Postmessage-demo and try it out.

Friends who like this article can follow my wechat public number and push some good articles irregularly.

This article is from Rockjins Blog, please contact the author for reprinting. Otherwise, legal liability will be investigated.