The sample address
prologue
- I saw an interview question on the Internet before: how to achieve communication between multiple tabs in the browser. I have three approaches in mind: using the WebSocket protocol, using LocalStorage, and using SharedWorker, a new feature of THE HTML5 browser.
- I will not introduce websocket here, full duplex communication naturally can achieve multiple TAB page communication, I believe that there are many tutorials on websocket to achieve chat room, I also used sock. IO to write an online chat room
- The next two methods are listening on localStorage and using SharedWorker
localstorage
- Localstorage is the storage space shared by multiple tabs in the browser, so it can be used to implement communication between multiple tabs (PS: Session is the session-level storage space, and each TAB is independent).
- Add a listener directly to the window object:
Window.onstorage = (e) => {console.log(e)}'storage', (e) => console.log(e))
Copy the code
- Onstorage and storage events, for bothNon-current pageThis function is triggered when you modify localStorage. The listener function is not triggered when you modify localStorage on the current page. LocalStorage = ‘b’; localStorage = ‘b’; localStorage = ‘b’;
localStorage.setItem('a', 'b')
Code, again, does not trigger the listener function.
webworker
- We all know that JavaScript is single-threaded, but browsers have threads such as GUI rendering threads, JS engine threads, event-firing threads, and asynchronous HTTP request threads.
- Webworker, as a new feature of the browser, can provide an extra thread to execute some JS code without affecting the browser user interface.
- Application scenarios: for example, pages containing time-consuming algorithm code will block threads affecting browser rendering, etc. At this point, the time-consuming code can be put into the Webworker (another thread) to execute.
- Note that this multithreading capability is not native to the JavaScript language, but is provided by the browser hosting environment.
- Ordinary Webworkers use it directly
new Worker()
This webworker can be createdThe current pageProprietary. Then there is a SharedWorker (SharedWorker), which can be used by multiple tabs and iframes. Next, how to use SharedWorker to realize the communication between tabs is introduced.
SharedWorker
- SharedWorker can be used by multiple Windows, but the tabs must be of the same origin (same protocol, host and port number).
- Start by creating a new JS file
worker.js
, the specific code is as follows:
// sharedWorker can use js files directly to the server instead of packing them into the projectlet data = ' '
onconnect = function (e) {
let port = e.ports[0]
port.onmessage = function (e) {
if (e.data === 'get') {
port.postMessage(data)
} else {
data = e.data
}
}
}
Copy the code
-
The code on the Webworker side (let’s call it that) is like this: simply register an onMessage event that will be triggered when the client (using the sharedWorker’s TAB) sends a message.
-
Note that webworker cannot be used locally, due to the security mechanism of the browser itself, so my example is also placed on the server, worker.js and index.html are in the same directory.
-
Because the communication between the client and webworker is not full-duplex like that of websocket, the client sends and receives data in two steps. There will be two buttons in the example, corresponding to a request to send data to the sharedWorker and a request to get data, but they are essentially the same event — send a message.
-
The Webworker will make a judgment. When the data passed is “get”, it will send the value of the variable data back to the client. In other cases, it will store the data passed by the client into the data variable. Here is the client code:
// This code is required to open the page and register the SharedWorker, indicating that the worker.port.start() method is specified to establish a connection with the workerif (typeof Worker === "undefined") {
alert('Current browser does not support Webworkers')}else {
let worker = new SharedWorker('worker.js')
worker.port.addEventListener('message', (e) => {
console.log('Data from worker:', e.data)
}, falseWorker.port.start () window.worker = worker} // The postMessage method is used to fetch and send messages'get'Indicates to obtain data. window.worker.port.postMessage('get')
window.worker.port.postMessage('Send message to worker')
Copy the code
- Page A sends data to the worker, and then opens page B to call
window.worker.port.postMessage('get')
, can receive the data sent to the worker by page A. - Reference: developer.mozilla.org/zh-CN/docs/…