preface

In a previous project, there was a requirement like this:

The site has a websocket message push mechanism and allows multiple pages to be opened. However, due to the original design of websocket mechanism, even if multiple browser TAB pages are opened for the same account information, Also, only the websocket channel of the last TAB page is alive, and all websockets of other pages are closed. As a result, only the message of the last page is synchronized in real time, and the message of other pages cannot be updated. However, the product requires that since multiple TAB pages are allowed, the message synchronization on all pages should be the same.

The most straightforward way to do this is to change the webSocket channel mechanism to allow multiple channels for the same account, but due to historical baggage and other reasons, changing this mechanism can be a pain in the neck (several projects are based on this design). So the next best thing is that when a websocket channel on one page receives a message, it broadcasts it to the other pages, lets the other pages know about it, and passes the data along.

In field

This involves the information transfer of multiple TAB pages, which I was able to do when I made chrome Extension. But this is not an extended application. PostMessage is also used for messaging across different pages, but postMessage can only be used for embedded pages and is not suitable for this scenario.

But the back or found a way, that is to use localstorage to deal with.

We know that localStorage will share the same domain name. So this makes it possible to capture and share data. Here’s an example:

For example, IF I execute on the console of page A:

localStorage.setItem("name","zach")
Copy the code

I execute from the console on another TAB page B of the same domain:

localStorage.getItem("name")
"zach"
Copy the code

You can get the data at this point

So data sharing is fine. So how to notify, especially when the data changes, just storage provides a listening method, when the storage changes, can be triggered by listening to the event, see: Window: storage event

It’s written like this:

window.addEventListener('storage', () => {
  // When local storage changes, dump the list to
  // the console.
  console.log(JSON.parse(window.localStorage.getItem('sampleList')));
});
Copy the code

Or is it

window.onstorage = () => {
  // When local storage changes, dump the list to
  // the console.
  console.log(JSON.parse(window.localStorage.getItem('sampleList')));
};
Copy the code

Let’s practice by listening to this function on the console of page B:

window.addEventListener('storage', () => {
  // When local storage changes, dump the list to
  // the console.
  console.log("change after:" + window.localStorage.getItem('name'));
});
Copy the code

When I setItem change the value of name, it will trigger and print. The removeItem behavior also changes.

That is, every time I want to notify another TAB page site, ALL I need to do is have the other page listen for the event, and then the page that I want to broadcast changes the value of localStorage. Because if you change it, it will be broadcast.

defects

Later tests found that there was one case that could not be synchronized, that is, chrome browser on the same PC, if it is the behavior of different users under login. I found that although the domain name is the same, localStorage does not share it.

For example, I log in to Chrome as user A, open the site foo.com, and write A localstorage record. At this time, user B logs in to chrome and opens foo.com. At this time, his localstorage is actually empty and will not be associated with user A’s information.

So MY guess is that Chrome is isolated under different user logins. But under normal circumstances, fewer people would do it.

conclusion

In this way, we can achieve the same domain site in the same browser after multiple open messaging mechanism.


See my personal site: kebingzao.com/ for more good articles