preface

First, let’s look at an application scenario:

  1. Page A has a list, each row has an “Edit” button, click the button to open a new TAB TAB page B;
  2. Page B is a page for editing a line of content, and page B has a “Save and close” button;
  3. Click the “Save and close” button of page B, page B will close, and send a communication to page A, informing page A that the list needs to be refreshed;
  4. Page A receives the communication from page B. Page A refreshes the list according to the agreed identifiers on the two pages.

This demand in some PC side of the background management system is often encountered, that is, we call the browser between different TAB page communication, the implementation method is not difficult, we can use today to talk about the two methods to achieve.

A, Broadcast Channel

1. The role

The Broadcast Channel API enables simple communication between different browser Windows, tabs, frames, and iframe contexts (usually different pages on the same website) in the same browser.

Characteristics of 2.

By creating a BroadcastChannel object that listens to a channel, you can receive all messages sent to that channel. They can simply “subscribe” to specific channels by constructing BroadcastChannels and communicate full-duplex (two-way) between them.

3. Usage

3.1 Creating or Joining a Channel

By creating a BroadcastChannel object, a client joins a specified channel. All you need to do is pass in a single argument to the constructor: the channel name.

// Create a broadcast channel
const bc = new BroadcastChannel('myChannel');
Copy the code

3.2 Sending Messages

Just call the postMessage() method on the BroadcastChannel object. The argument to this method can be any object. The simplest example is sending a text message that defines a unique identity for two pages.

// Send a message
bc.postMessage('updateList');
Copy the code

3.3 Receiving Messages

When a message is sent, a Message event is emitted on all BroadcastChannel objects connected to the channel. There is no default behavior for this event, but the onMessage event can be used to process messages.

// Join the broadcast channel
const bc = new BroadcastChannel('myChannel');
// Receive the message
bc.onmessage = function (e) { console.log(e); }
Copy the code

If we print e, we can see the following contents:

The most useful attributes are the three highlighted:

  • Currenttarge. name: indicates the current broadcast channel
  • Data: indicates the sent message
  • Origin: indicates the current source

3.4 Disconnecting from the Channel

You can leave the channel by calling the BroadcastChannel object’s close() method. This disconnects the object from its associated channel and allows it to be garbage collected.

// Disconnect the channel connection
bc.close()
Copy the code

4. Implementation cases

Next, back to the application scenario from the beginning, we use the API to implement this requirement.

Page B code

// Create channel
const bc = new BroadcastChannel("myChannel");

// Send a message with a unique identifier
bc.postMessage("updateList");
Copy the code

Page A code

// Join the channel
const bc = new BroadcastChannel("myChannel");

// Receive the message
bc.onmessage = function (e) {

// We need to check whether it is homologous
// Filter out other origin messages, this judgment is very important, do not add a lot of may be XSS attack!
if (e.origin === location.origin) {

  // Secondly, it is best to determine whether the sent message is the unique identifier agreed on both sides, so as to carry out accurate operation
  if (e.data === "updateList") {
    // Refresh the list operation.// Disconnect the channel connection
    bc.close()
  }
}
};
Copy the code

5. Browser compatibility

6. Summary

The Broadcast Channel API is a very simple API that contains an interface for communication between contexts. There is no message-transport protocol defined, so different documents in different contexts need to implement it themselves: the specification makes no protocols or requirements for this. The second is that it only supports same-origin. For different sources, we have to implement this in another way, window.postMessage.

Second, the window postMessage

1. The role

Just like the Broadcast Channel API, it allows different pages to communicate with each other.

Characteristics of 2.

The window.postMessage() method can communicate between any page in the case of different sources, providing a controlled mechanism to circumvent cross-domain restrictions. This approach also has some security implications, as pages from different sources can attack you with XSS if there are no restrictions. However, as long as used correctly, this method is quite safe.

3. Usage

3.1 Initiating Communication

window.opener.postMessage(message,targetOrigin);
Copy the code

Message: data to be sent to another window. It will be serialized by a structured cloning algorithm. This means that you can safely pass data objects to the target window without having to serialize them yourself. Here we simply send a single character as a unique identifier for both parties.

TargetOrigin: Specifies which Windows can receive message events via the origin property of the window, which can be a string ‘*’ (for unrestricted) or a URI.

Pay attention to

  • If any of the protocol, host address, or port of the target window does not match the value provided by targetOrigin, the message will not be sent. A message will only be sent if all three match.
  • This mechanism is used to control which Windows a message can be sent to. For example, when sending a password using postMessage, this parameter is particularly important. It is necessary to ensure that its value is exactly the same as the Origin property of the intended recipient of the message containing the password to prevent the password from being intercepted by a malicious third party.
  • If you know exactly which window the message should be sent to, always provide a targetOrigin with the exact value, not *. Not providing an exact target will result in data being leaked to any malicious site interested in the data.

3.2 Monitoring Communication

window.addEventListener("message".(e) = > { console.log(e); });
Copy the code

Listen directly for message events. The e printed here is the same as the content received by the Broadcast ChannelAPI, and can be directly operated by the relevant properties returned.

4. Implementation cases

Page B code

// Initiate communication, agree on the unique identifier, and can be listened to the page source
window.opener.postMessage("updateLiveList", location.origin);
Copy the code

Page A code

// Listen for the message event
window.addEventListener("message".(e) = > {
  // Check whether it is the same origin
  if (e.origin === location.origin) {
  
    // Whether the received message is the agreed unique identifier
    if(e.data === "updateList") {
      // Refresh the list operation. }}});Copy the code

5. Browser compatibility

6. Security issues

  • If you do not want to receive messages from other sites, do not add any event listeners for message events. This is a completely foolproof way to avoid security issues.
  • If you do want to receive messages from other sites, always verify the identity of the sender using the Origin and source properties. Any window can send messages to any other window, and you cannot guarantee that unknown senders will not send malicious messages and XSS attacks against you.
  • When you use postMessage to send data to other Windows, always specify the exact destination origin, not ‘*’. A malicious site can change the location of a window without your knowledge, so it can intercept data sent using postMessage.

Third, summary

  • Broadcast channels and window.postMessage can communicate across pages
  • Broadcast channels can only be used for communication between same-origin pages, whereas window.postMessage can be used for communication between any page
  • Based on the same origin policy of Broadcast Channel, it cannot transfer data across domains. In the cross-domain case, we can only handle it using window.postMessage
  • Broadcast Channel Is more secure than window.postMessage. You are recommended to use Broadcast Channel for cross-page communication if no special requirements are met

If you think this article is helpful to you, please click a like to express your encouragement. Thank you!