homologous
BroadcastChannel
Simple communication between browser contexts (Windows, Tabs, Frames, or iframes) of the same source
API
- Sender: Used
BroadcastChannelIns.postMessage(message)
send - Recipient: Yes
BroadcastChannelIns.addEventListener('message',function)
- (on)message: triggered when data is sent.
- (on) onMessageError: Triggered when a message fails.
- BroadcastChannelIns. Close () : close the channel, will no longer receive;
demo
Send page
// pages/dispather.js
import Head from 'next/head';
import styles from '.. /styles/Home.module.css';
import { useState } from 'react';
export default function Dispather() {
const [message, setMessage] = useState(' ');
// Send a message
const handleSendMessage = () = > {
// The parameters of the new BroadcastChannel must be the same as those of the receiver
const channel = new BroadcastChannel('this_params_must_be_same');
channel.postMessage(message);
};
return (
<div className={styles.container}>
<Head>
<title>Dispatcher</title>
</Head>
<main className={styles.main}>
<h4>This is messege to be sent:</h4>
<input
value={message}
onChange={e= >{ setMessage(e.target.value); }} / ><br />
<button onClick={handleSendMessage}>click to send</button>
</main>
</div>
);
}
Copy the code
Receive page
// pages/receiver.js
import Head from 'next/head';
import styles from '.. /styles/Home.module.css';
import { useEffect, useState } from 'react';
export default function Receiver() {
// -- listen for messages receiving --
const handleListenMessage = () = > {
// The parameters of the new BroadcastChannel must be the same as those of the receiver
const channel = new BroadcastChannel('this_params_must_be_same');
console.log('This channel is working:', channel.name, '(channel.name)');
channel.onmessage = function (event) {
setMessage(event.data);
};
};
const [message, setMessage] = useState(' ');
// handleListenMessage cannot be broadcasted directly in a component because it has no BroadcastChannel API on the server side
useEffect(() = >{ handleListenMessage(); } []);// ReferenceError: BroadcastChannel is not defined
// handleListenMessage();
return (
<div className={styles.container}>
<Head>
<title>Receiver</title>
</Head>
<main className={styles.main}>
<h4>This is messege received:</h4>
<h4>{message}</h4>
<br />
</main>
</div>
);
}
Copy the code
Shared Worker
Ordinary workers run independently and their data are not connected to each other; Shared workers registered with multiple tabs can realize data sharing.
API
- Sender: Used
SharedWorkerIns.port.postMessage(message)
send - Recipient: Yes
SharedWorkerIns.port.addEventListener('message',function)
demo
Send page
import Head from 'next/head';
import styles from '.. /styles/Home.module.css';
import { useState, useEffect } from 'react';
export default function Dispather() {
const [message, setMessage] = useState(' ');
const [worker, setWorker] = useState(' ');
useEffect(() = > {
// new SharedWorker references the same script and must have the same name to share data
setWorker(new SharedWorker('/worker.js'.'this_name_must_be_same')); } []);// Send a message
const handleSendMessage = () = > {
worker.port.postMessage(message);
};
return (
<div className={styles.container}>
<Head>
<title>Dispatcher</title>
</Head>
<main className={styles.main}>
<h4>This is messege to be sent:</h4>
<input
value={message}
onChange={e= >{ setMessage(e.target.value); }} / ><br />
<button onClick={handleSendMessage}>click to send</button>
</main>
</div>
);
}
Copy the code
Receive page
import Head from 'next/head';
import styles from '.. /styles/Home.module.css';
import { useEffect, useState } from 'react';
export default function Receiver() {
const [worker, setWorker] = useState(' ');
useEffect(() = > {
setWorker(new SharedWorker('/worker.js'.'this_name_must_be_same')); handleListenMessage(); } []);// -- listen for messages receiving --
const handleListenMessage = () = > {
// new SharedWorker references the same worker
console.log('This worker is working:', worker);
if (worker.port) {
worker.port.onmessage = function (event) { setMessage(event.data); }; }};const [message, setMessage] = useState(' ');
return (
<div className={styles.container}>
<Head>
<title>Receiver</title>
</Head>
<main className={styles.main}>
<h4>This is messege received:</h4>
<h4>{message}</h4>
<br />
</main>
</div>
);
}
Copy the code
worker
// public/worker.js
// worker.js
const ports = new Set(a);// Triggered when linking
self.onconnect = event= > {
// Event. ports: MessageEvent; new SharedWorker: MessageEvent
const port = event.ports[0];
console.log(
The child thread worker's connect event is triggered when the parent thread port's new SharedWorker is set to:,
event.ports[0].'The total parent thread port has :',
ports
);
ports.add(port);
port.onmessage = e= > {
// port.onMessage listens for messages from the parent thread
console.log(e.data);
console.log(
The message event of the parent thread port is fired when the parent thread port is:,
port,
'the message is:',
e.data,
'The total parent thread port has :',
ports,
'To exclude myself and.'.Array.from(ports).filter(p= >p ! == port) );Array.from(ports)
.filter(p= >p ! == port)// Remove yourself when broadcasting the message
.forEach(p= > p.postMessage(e.data)); // Send messages to users in the link pool
};
};
Copy the code
LocalStorage
- Same-origin restriction: a source shares the same localStorage. A.meituan.com and b.meituan.com are two domain names and cannot share a storage. But the same TAB page can share localStorage
- Size limit :localStorage has a maximum limit of 5MB. If the localStorage is full, an error will be reported if you try to store more items, or if you try to store more items than the remaining capacity (QuotaExceededError 22).
API
-
Sender: window. LocalStorage. SetItem (‘ key ‘JSON. Stringify (value));
-
Receiver: window. AddEventListener (‘ storage ‘; function)
The event storage is raised only when value actually changes
demo
Send page
// pages/dispather.js
import Head from 'next/head';
import styles from '.. /styles/Home.module.css';
import { useState, useEffect } from 'react';
export default function Dispather() {
const [message, setMessage] = useState(' ');
// Send a message
const handleSendMessage = () = > {
window.localStorage.setItem('localStore'.JSON.stringify(message));
};
return (
<div className={styles.container}>
<Head>
<title>Dispatcher</title>
</Head>
<main className={styles.main}>
<h4>This is messege to be sent:</h4>
<input
value={message}
onChange={e= >{ setMessage(e.target.value); }} / ><br />
<button onClick={handleSendMessage}>click to send</button>
</main>
</div>
);
}
Copy the code
Accept the page
import Head from 'next/head';
import styles from '.. /styles/Home.module.css';
import { useEffect, useState } from 'react';
export default function Receiver() {
useEffect(() = >{ handleListenMessage(); } []);// -- listen for messages receiving --
const handleListenMessage = () = > {
window.onstorage = function (e) {
console.log(e);
if (e.key === 'localStore') {
const data = JSON.parse(e.newValue); setMessage(data); }}; };const [message, setMessage] = useState(' ');
return (
<div className={styles.container}>
<Head>
<title>Receiver</title>
</Head>
<main className={styles.main}>
<h4>This is messege received:</h4>
<h4>{message}</h4>
<br />
</main>
</div>
);
}
Copy the code
The homologous
iframe
API
- Sender: Used
otherWindow.postMessage(message, targetOrigin, [transfer]);
- Receiver:
window.addEventListener('message', function)
- OtherWindow: used by parent page
dom.contentWindow/ [iframename]
Get a reference to the child page Window; Subpage usagee.source/ window.top/ window.parent
Gets a reference to the parent page window - In non-homogenous cases, you cannot access the DOM of other Windo, so you cannot access the Window directly, but you can call methods
- TargetOrigin: Specifies which Windows can receive message events via the origin property of the window. The value can be a string “*” (for unrestricted) or a URI
- Do not add event listening to messages if you do not want to receive messages from other sites. If you want to receive messages from other websites, you need to verify the identity of the sender with the Origin and source properties
demo
Send page
// localhost:3000/dispather
import Head from 'next/head';
import styles from '.. /styles/Home.module.css';
import { useState, useEffect } from 'react';
export default function Dispather() {
const [message, setMessage] = useState(' ');
const handleCallChildFun = () = > {
// Get the child page
// const iFrame = document.getElementById('iframe');
// iFrame.contentWindow.postMessage(message, 'http://localhost:3001/receiver');
console.log('The parent page calls the postMessage method of the child page, passing the message :', message);
const iFrameWindow = iframewindow;
iFrameWindow.postMessage(message, 'http://localhost:3001/receiver');
};
return (
<div className={styles.container}>
<Head>
<title>Dispatcher</title>
</Head>
<main className={styles.main}>
<h4>This is messege to be sent:</h4>
<input
value={message}
onChange={e= >{ setMessage(e.target.value); }} / ><br />
<button onClick={handleCallChildFun}>Pass the message to the parent page</button>
<br />{/ *<iframe id="iframe" style={{ width: '80vw', height: '60vh'}}src="http://localhost:3001/receiver" />* /}<iframe name="iframewindow" style={{ width: '80vw', height: '60vh'}}src="http://localhost:3001/receiver" />
</main>
</div>
);
}
Copy the code
Receive page
// localhost:3000/receiver
import Head from 'next/head';
import styles from '.. /styles/Home.module.css';
import { useEffect, useState } from 'react';
export default function Receiver() {
useEffect(() = > {
// The child page listens to receive messages
window.addEventListener(
'message'.e= > {
/** eventInit : Origin String message field, in this case the parent page lastEventId String Channel String Source Object Window object (window.parent/window.top) ports Array
} */
console.log('Child page receives message :', e.data, e);
if (e.origin === 'http://localhost:3000') {
console.log(window.top); setMessage(e.data); }},false); } []);const [message, setMessage] = useState(' ');
return (
<div className={styles.container}>
<Head>
<title>Receiver</title>
</Head>
<main className={styles.main}>
<h4>This is messege received:</h4>
<h4>{message}</h4>
<br />
</main>
</div>
);
}
Copy the code