homologous

BroadcastChannel

Simple communication between browser contexts (Windows, Tabs, Frames, or iframes) of the same source

API

  • Sender: UsedBroadcastChannelIns.postMessage(message)send
  • Recipient: YesBroadcastChannelIns.addEventListener('message',function)
  1. (on)message: triggered when data is sent.
  2. (on) onMessageError: Triggered when a message fails.
  3. 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: UsedSharedWorkerIns.port.postMessage(message)send
  • Recipient: YesSharedWorkerIns.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: UsedotherWindow.postMessage(message, targetOrigin, [transfer]);
  • Receiver:window.addEventListener('message', function)
  1. OtherWindow: used by parent pagedom.contentWindow/ [iframename]Get a reference to the child page Window; Subpage usagee.source/ window.top/ window.parentGets a reference to the parent page window
  2. In non-homogenous cases, you cannot access the DOM of other Windo, so you cannot access the Window directly, but you can call methods
  3. 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
  4. 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