preface
The browser can open many different ones, and sometimes you need to use cross-page communication when you need to transfer data across the page or trigger a special effect in the page. How? Let’s take a look at how browsers cross pages
Cross-page communication between cognates
1.BroadcastChannel
Description of BroadcastChannel in MDN
The Broadcast Channel API allows simple communication between browsing contexts (that is windows, tabs, frames, or iframes) with the same origin (usually pages from the same site).
The BroadcastChannel API allows simple communication between the same source (typically pages from the same website) in a browser context (Windows, Tabs,frames, or Iframes)
-
Communication Principles (Image source)
As you can see, a BroadcastChannel is created in a web pageCommunication frequency, all pages added to this band can receive and send messages, but they must beThe same source.
-
Onmessage: BroadcastChannel object events: onMessage: triggered when listening to data sent; Messageerror: triggered when a messageerror is heard. PostMessage (MSG: any): send a message; Close () : close the channel;
-
As an example of BroadcastChannel, let’s write a demo: we need to write two pages, one that sends the message and one that receives the message and returns the received information to the first page
Send message page:
<html> <head> <title>sendMessage</title> </head> <body> <div> <p> <input id="input" value="" /> </p> <p> <button id="btn">Send a message</button> </p> <p id="getMsg"></p> </div> <script> const channel = new BroadcastChannel('test_channel'); const input = document.querySelector('#input'); const btn = document.querySelector('#btn'); const getMsg = document.querySelector('#getMsg'); // Send the message btn.addEventListener('click', (e) => { channel.postMessage(input.value); }, false); // Interface feedback channel.onmessage = function(event) { getMsg.innerText = event.data; } </script> </body> </html> Copy the code
Receive message page:
<html> <head> <title>getMessage</title> </head> <body> <p id="showMsg"></p> <script> const channel = new BroadcastChannel('test_channel') const showMsg = document.querySelector('#showMsg'); channel.onmessage = function(event) { showMsg.innerText = event.data; channel.postMessage('Received message:${event.data}`); } </script> </body> </html> Copy the code
After opening both pages and running, you can see that the messages sent by sendMessage page can be received by getMessage.
-
compatibility
2.sharedWorker
The SharedWorker interface represents a specific kind of worker that can be accessed from several browsing contexts, such as several windows, iframes or even workers. They implement an interface different than dedicated workers and have a different global scope
SharedWorker represents a particular type of worker to access several browser contexts, such as several Windows, Iframes, or even workers. They implement a different interface from dedicated workers and have a different global scope.
-
SharedWorker requires us to manually implement a worker running in the background of the browser, and the page carries out links and information transfer through the worke
-
As in the previous example, you need to create two HTML pages, one for sending messages and one for receiving messages. In addition, implement a worker that holds the page that created the link
Worker. Js:
// worker.js
const ports = [];
// Trigger when linking
onconnect = (event) = > {
const port = event.ports[0];
ports.push(port);
port.onmessage = (e) = > {
ports.filter(p= >p ! == port)// Get rid of yourself when broadcasting messages
.forEach(p= > p.postMessage(e.data)); // Send a message to users in the link pool
};
}
Copy the code
Send message page:
<html>
<head>
<title>shareWorker_send</title>
</head>
<body>
<div>
<p>
<input id="input" value="" />
</p>
<p>
<button id="btn">Send a message</button>
</p>
<p id="getMsg"></p>
</div>
<script>
const worker = new SharedWorker('./worker.js');
const input = document.querySelector('#input');
const btn = document.querySelector('#btn');
const getMsg = document.querySelector('#getMsg');
worker.port.start(); / / open the worker
btn.onclick = function() {
worker.port.postMessage(input.value);
}
worker.port.onmessage = function(event) {
getMsg.innerText = event.data;
}
</script>
</body>
</html>
Copy the code
Receive message page:
<html>
<head>
<title>shareWorker_get</title>
</head>
<body>
<p id="showMsg"></p>
<script>
const worker = new SharedWorker('./worker.js');
const showMsg = document.querySelector('#showMsg');
worker.port.start();
worker.port.onmessage = function(event) {
showMsg.innerText = event.data;
worker.port.postMessage('Received message:${event.data}`);
}
</script>
</body>
</html>
Copy the code
Run instance:
- compatibility
3. Listen for localStorage events
The principle is to listen to the storage event, to the page to make the corresponding action.
- For example,
Send page:
<html>
<head>
<title>changeStorage</title>
</head>
<body>
<div>
<p>
<input id="input" value="" />
</p>
<p>
<button id="btn">Send a message</button>
</p>
<p id="getMsg"></p>
</div>
<script>
const input = document.querySelector('#input');
const btn = document.querySelector('#btn');
const getMsg = document.querySelector('#getMsg');
localStorage.setItem('test'.'defaultValue'); // Set a default value
btn.onclick = function() {
localStorage.setItem('test', input.value);
}
</script>
</body>
</html>
Copy the code
Receive page:
<html>
<head>
<title>getStorage</title>
</head>
<body>
<p id="showMsg"></p>
<script>
const showMsg = document.querySelector('#showMsg');
window.addEventListener('storage', (event) => {
showMsg.innerText = `key:${event.key}\ n old values:${event.oldValue}New value: \ n${event.newValue}`;
}, false);
</script>
</body>
</html>
Copy the code
Running result:
- Listen for compatibility of storage events
4.window.opener
-
Window.opener refers to the page before the page opens. For example, if a B.HTML page is opened with window.open in a.HTML, then window.opener in a B.HTML page refers to the A.HTML page. While a.html is not opened from any page, window.opener is empty;
-
For example, write a parent page to open a new page, and then through the new open page to change the demo of the parent page
The parent page
<html> <head> <title>parent</title> </head> <body> <a href='./child.html' target="_blank">child.html</a> <p id="childModify">default</p> </body> </html> Copy the code
Child pages
<html> <head> <title>child</title> </head> <body> <p id="showMsg"></p> <script> if (window.opener) { const showMsg = document.querySelector('#showMsg'); showMsg.innerHTML = 'I opened it through the parent page parent.html'; window.opener.document.querySelector('#childModify').innerText = 'I am through the child page modification! '; // Change the parent page display } </script> </body> </html> Copy the code
Run it:
Page communication across domains
1.iframe
Sometimes there are two businesses that need to communicate with each other, but the two pages are on different domains. At this point we can communicate through the iframe
- The principle of
By gettingiframe
The object’swindow
towindow
Send a messageiframe
Child pages by listeningmessage
Event takes action accordingly - For example,
To simulate two different source pages, we need to set up two different portsThe web service
, the following isnode
The code (usingkoa
)
Node Server:
// app.js
const Koa = require('koa');
const koaStatic = require('koa-static');
const path = require('path');
const app = new Koa();
app.use(koaStatic(path.resolve(__dirname, 'assets'.'commiunation')))
app.listen(9999, () = > {console.log(`server running at 9999`);
})
app.listen(8888, () = > {console.log(`server running at 8888`);
})
Copy the code
We are listening on port 9999 and port 8888 respectively. The parent page is opened with port 9999. The iframe path of the parent page is filled with the URL of port 8888
The parent page
<html>
<head>
<title>windowPostMessage</title>
</head>
<body>
<div>
<p>
<input id="input" value="" />
</p>
<p>
<button id="btn">Send a message</button>
</p>
<p id="getMsg"></p>
</div>
<! -- different source from parent page -->
<iframe src='http://localhost:8888/window/get.html' id="iframe"></iframe>
<script>
const input = document.querySelector('#input');
const btn = document.querySelector('#btn');
const getMsg = document.querySelector('#getMsg');
const ifm = document.querySelector('#iframe');
btn.addEventListener('click', (e) => {
ifm.contentWindow.postMessage(input.value, The '*'); // Send a message to the iframe child page
}, false);
window.addEventListener('message', (e) => {
getMsg.innerText = e.data;
}, false);
</script>
</body>
</html>
Copy the code
The iframe page
<html>
<head>
<title>windowGetMessage</title>
</head>
<body>
<p id="showMsg"></p>
<script>
const showMsg = document.querySelector('#showMsg');
window.addEventListener('message', (event) => {
showMsg.innerText = event.data;
event.source.postMessage('Message received:${event.data}`.The '*'); // Send a message to the parent page
})
</script>
</body>
</html>
Copy the code
Running result:
2. Server based
In addition to iframe for cross-domain cross-page communication, you can also use the server side for interpage communication. The principle of communication is actually very simple, that is, the pages that need to communicate are linked to the same server. A page sends messages to the server, and the server forwards the information to other pages that are linked to the server. Let’s use WebSocket in HTML5 as an example
- For example,
websocket
You need to communicate through the server, so you need to make a WebSocket server:
'use strict';
const http = require('http');
const WebSocket = require('ws');
const server = http.createServer((req, res) = > {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end(' ');
});
const connObj = {}; // Store the socket object that entered the link
const wss = new WebSocket.Server({ server, });
wss.on('connection', (ws) => {
onMessage(ws);
connObj[ws.protocol] = ws; // Record the incoming socket object
})
// Send the message push
function onMessage(ws) {
ws.on('message', (message) => {
message = JSON.parse(message);
// Send a message to the specified user
if (connObj[message.to]) {
connObj[message.to].send('Message received :' + message.data);
}
})
}
server.listen(12345, () = > {console.log(12345);
})
Copy the code
Write two front-end pages to test pageA:
8888
pageA
9999
pageB
Based on the service terminal communication, in addition to WebSocket, and SSE, interested can go to check, here is not much to say ~!
3.visibilityState
The principle is that every time the page will be triggered, and then manually to call the interface to get information, specific use
summary
With the article looking at cross-page communication in both homologous and cross-domain contexts, let’s summarize
-
Homologous cross-page communication
BroadcastChannel
: Simple to use, but poor compatibility;sharedWorker
: The use is complex and requires manual writing of a worker for link;- Listening for localStorage events: by listening for Windows
storage
Events, localStorageModify theDifferent Instances of Chrome can also trigger the storage event. window.opener
: Can find the specified browser window for message delivery;- There are others through the browser
WebSql
和IndexDb
You can also transfer information across pages;
-
Cross-page communication across domains
iframe
: Sends a message through the iframe of the parent pageWebSocket
: By establishing acontinuousTCP
The link communicates with the server. If the link needs to be established for a long time, the link needs to be sentThe heartbeat packetsMaintaining TCP linksvisibilityState
: Triggered when the page enters, to manually call the back-end information to achieve the effect of data update
There are many ways to communicate across pages in the browser, and there may be many that have not been mentioned in this article. If there is any error, please point out ~~