1. What is postMessage

PostMessage is a new API introduced in HTML5 that enables cross-window and cross-domain communication. PostMessage is similar to Ajax but is not restricted by the same origin policy and communicates with both clients.

2. PostMessage API introduction

2.1. Send data

Grammar:

quoteWindow.postmessage(data, origin, [transfer])
Copy the code

quoteWindow

Where quoteWindow represents a reference to another window, which is the party to which data is sent (receiving data), and can be of the following type

  1. Iframe contentWindow
<body>
    <iframe class="childIframe" scr="http://XXX:8080"></iframe>
    <script>
        // Get iframe contentWindow
        const win = document.querySelector('.childIframe').contentWindow
    </script>
</body>
Copy the code
  1. performwindow.open()The object returned by the
<body>
    <script>
        // Get a reference to the window.open() window
        const win = window.open('http://XXX:8888')
    </script>
</body>
Copy the code
  1. Named or numerically indexedwindow.frames
<body>
    <script>
        const iframes = window.frames
    </script>
</body>
Copy the code

data

Data represents the data to be sent. MDN says: Data represents the data to be sent to other Windows. It will be serialized by a structured cloning algorithm. This means you can safely pass data objects to the target window without having to serialize them yourself. [1]

origin

Origin allows you to specify which Windows can receive the message event. The value can be:

  • “*”

Indicates that there is no restriction

  • The URL address

Indicates that only the window at that URL can receive the message. This design is particularly important, because we need to specify the window to receive the event when transmitting some sensitive information to prevent malicious attacks.

transfer

Is a string of Transferable objects that are passed along with Message. Ownership of these objects is transferred to the receiver of the message, and ownership is no longer retained by the sender.

To summarize

To send data, use the postMessage method. If you want that window to send data, call the postMessage method of that window and pass in the relevant parameters in the method.

2.2 Receiving data

grammar

window.addEventListener('message'.(e) = > {
    // ...
})
Copy the code

Listen for a **message** event on the page that needs to receive the message, which is triggered when other Windows send data, and then execute the corresponding event function.

There are three important properties in the received event object:

  1. Origin; Indicates the source of the sending message window. You can use this property to determine whether the source is secure
  2. The data; Represents the data sent by the send message window
  3. The source; Represents a reference to the sending message window that can be used to return data to the window that sent the message

3. Specific use

Define the parent window:

<body>
  <h1>This is parent window</h1>
  <input type="text" class="inp">
  <button class="send">Send a message to iframe</button>
  <div class="contents">
    <p>Received information</p>
    <ul class="messages">

    </ul>
  </div>
  <iframe src="child.html" frameborder="3" class="child-iframe" height="600" width="800"></iframe>
  <script>
    // The parent page listens for message events and accepts messages sent by iframe
    window.addEventListener('message'.e= > {
      if(e.origin ! = ='http://127.0.0.1:5500') { // Verify the peer's identity
        return
      }
      const box = document.querySelector('.messages')
      box.innerHTML += '<li> Receives a new message:${e.data}And from the${e.origin}</li>`;
    });
    // Iframe reference
    const win = document.querySelector('.child-iframe').contentWindow
    document.querySelector('.send').addEventListener('click'.() = > {
      const msg = document.querySelector('.inp').value
      win.postMessage(msg, The '*') // Use *, which can also be the IFrame URL
      document.querySelector('.inp').value = ' '
    })
  </script>
</body>
Copy the code

Defining child Windows

<body>
  <h1>This is iframe child page</h1>
  <input type="text" class="inp">
  <button class="send">Send a message to the husband window</button>
  <div class="contents">
    <p>Received information</p>
    <ul class="messages">

    </ul>
  </div>
  <script>
    let parentWin
    // Listen for messages from the parent page
    window.addEventListener('message'.e= > {
      if(e.origin ! = ='http://127.0.0.1:5500') { // Verify the peer's identity
        return
      }
      // Send a reference to the window object of the detail window, call the postMessage method of the object to communicate with the parent page, and of course use window.parent to communicate
      parentWin = e.source
      const box = document.querySelector('.messages')
      box.innerHTML += '<li> receives a new message:${e.data}And from the${e.origin}</li>`
    })
    console.log(window.parent.location)

    document.querySelector('.send').addEventListener('click'.() = > {
      const msg = document.querySelector('.inp').value
      window.parent.postMessage(msg, The '*') // 
      document.querySelector('.inp').value = ' '
    })
  </script>
</body>
Copy the code

This enables communication between parent and child Windows. The diagram below:

PostMessage can also realize cross-domain communication, etc., which will be studied in the future.

4. Modify the style of DOM nodes in iframe

4.1. Modify after obtaining the element

window.onload = function () {
    let dom = document.getElementById('frame').contentWindow.document.getElementById('selector')
    / / modify style
    dom.style.color = "red"
    / / modify the class
    dom.classList.add('box')}Copy the code

4.2. Add CSS styles to iframe headers

You can’t get the DOM if an element is added dynamically, so you can add CSS styles.

let header = document.getElementById('frame').contentWindow.document.getElementById('header')
const CSS_STR = ` .box { color: red } `
const style = document.createElement('style')
style.innerText = CSS_STR
header.appendChild(style)
Copy the code

5. Compatibility

More articles

  • How to efficiently and conveniently operate State in React. Js