Iframe Cross-domain Communication (postMessage)

preface

Cross-domain simply means that different domains request resources from each other, such as AJAX requests, and the browser intercepts the response result based on the same origin policy, which is a security limitation imposed by browsers on JavaScript. Same-origin refers to the same domain name, protocol, and port. If one of them is different, it is cross-domain

Demand background

In the Web project, iframe is embedded into another third-party Web project. When a button is clicked in the third-party Web project, the global function of the Web project is called in real time to open a global popup or redirect. At this time, there is data interaction between the two projects, which obviously violates the same origin policy. The postMessage method under the window object introduced in HTML5 standard can allow scripts from different sources to communicate asynchronously in a limited way, and can achieve cross-text file, multi-window, cross-domain messaging

compatibility

As you can see, postMessage is well supported in all major browsers except the lower versions of Internet Explorer

grammar

Otherwindow.postmessage (message, targetOrigin, [transfer]);

  • OtherWindow: Target window (the window from which you want to send cross-domain messages), for example, iframe.contentWindow
  • Message Indicates the data to be sent
  • TargetOrigin Specifies the address (URL) of the target window, or the string ‘*’ indicating that unlimited, any URL is allowed to be sent
  • Transfer: A string of Transferable objects passed at the same time as Message. Ownership of these objects is transferred to the receiver of the message, and ownership is no longer retained by the sender.

use

Let’s assume that we now have two pages from different sources, the parent page address: http://a.index.com, and the child page address: http://b.index.com, and the parent page introduces the child page through iframe

<! - Anderson, ndex. HTML - > < h1 > parent page < / h1 > < iframe id = "iframe SRC =" http://b.index.com "> < iframe >Copy the code

① The parent page sends a message to the child page

const iFrame = document.getElementById('iframe') <! Iframe.onload = function(){<! -- the iFrame. ContentWindow get iFrame window object - > iFrame. ContentWindow. PostMessage (' parent page send message, 'http://b.index.com'); }Copy the code

② The child page receives the message from the parent page

The message event window.addEventListener('message',e=>{<! If (e.ogin ==='http://a.index.com'){console.log(e.ogin) // parent page URL, Here is http://a.index.com console.log(e.ource) // parent page window object, All equal to window.parent/window.top console.log(e.ata) // messages sent by the parent page}},false)Copy the code

PostMessage: otherWindow is the window object of the window to which you want to send data

Window. The parent. PostMessage (' child pages to send messages, 'http://a.index.com')Copy the code

④ The parent page receives the message from the child page. The communication logic is the same as that of the child page

window.addEventListener('message',e=>{ <! If (e.ogin ==='http://b.index.com'){console.log(e.ogin) // subpage URL, Here is the http://b.index.com console.log(e.ource) // child page window object, Full equal to iframe.contentWindow console.log(e.ata) // messages sent by child page}},false)Copy the code

Pay attention to the point

  • The window in window.postMessage refers to the window you want to send a cross-domain message to (the target window you need to communicate to), not the window of its own window
    • Parent page: The parent page sends cross-domain information to the child page. Window is the window of the child page pointed to by the embedded iframe in the parent page, that is, iframe.contentWindow
    • Child page: the child page sends cross-domain information to the parent page. Window is the parent page’s window. In this case, because the child page is embedded in the parent page, for the child page, window is top or parent
  • The message must be sent after the sub-page in the iframe is loaded. Otherwise, the sub-page cannot receive the message
  • When listening for message events, you need to check the origin of the message