Skip to content

跨标签通讯

1. LocalStorage + Storage Event

发送页面 (send.html)

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>LocalStorage Send</title>
</head>
<body>
    <h2>发送数据到 LocalStorage</h2>
    <input type="text" id="inputData" placeholder="输入数据">
    <button id="saveBtn">保存数据</button>
    <script>
        document.getElementById('saveBtn').onclick = function() {
            const data = document.getElementById('inputData').value;
            localStorage.setItem('sharedData', data);
            alert('数据已保存到 LocalStorage!');
        };
    </script>
</body>
</html>

接收页面 (receive.html)

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>LocalStorage Receive</title>
</head>
<body>
    <h2>接收 LocalStorage 数据</h2>
    <script>
        window.addEventListener('storage', function(event) {
            if (event.key === 'sharedData') {
                alert('接收到的数据: ' + event.newValue);
            }
        });
    </script>
</body>
</html>
2. BroadcastChannel API

发送页面 (send.html)

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>BroadcastChannel Send</title>
</head>
<body>
    <h2>发送数据到 BroadcastChannel</h2>
    <input type="text" id="inputData" placeholder="输入数据">
    <button id="sendBtn">发送数据</button>
    <script>
        const channel = new BroadcastChannel('my_channel');

        document.getElementById('sendBtn').onclick = function() {
            const data = document.getElementById('inputData').value;
            channel.postMessage(data);
            alert('数据已发送到 BroadcastChannel!');
        };
    </script>
</body>
</html>

接收页面 (receive.html)

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>BroadcastChannel Receive</title>
</head>
<body>
    <h2>接收 BroadcastChannel 数据</h2>
    <script>
        const channel = new BroadcastChannel('my_channel');

        channel.onmessage = function(event) {
            alert('接收到的数据: ' + event.data);
        };
    </script>
</body>
</html>
3. Service Workers

发送页面 (send.html)

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Service Worker Send</title>
</head>
<body>
    <h2>发送数据到 Service Worker</h2>
    <input type="text" id="inputData" placeholder="输入数据">
    <button id="sendBtn">发送数据</button>
    <script>
        if ('serviceWorker' in navigator) {
            navigator.serviceWorker.register('service-worker.js').then(function() {
                console.log('Service Worker 注册成功');
            });

            document.getElementById('sendBtn').onclick = function() {
                const data = document.getElementById('inputData').value;
                navigator.serviceWorker.ready.then(function(registration) {
                    registration.active.postMessage(data);
                    alert('数据已发送到 Service Worker!');
                });
            };
        }
    </script>
</body>
</html>

接收页面 (receive.html)

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Service Worker Receive</title>
</head>
<body>
    <h2>接收 Service Worker 数据</h2>
    <script>
        if ('serviceWorker' in navigator) {
            navigator.serviceWorker.register('service-worker.js').then(function() {
                console.log('Service Worker 注册成功');
            });

            navigator.serviceWorker.onmessage = function(event) {
                alert('接收到的数据: ' + event.data);
            };
        }
    </script>
</body>
</html>

service-worker.js

js
self.addEventListener('message', function(event) {
    const data = event.data;
    clients.matchAll().then(clients => {
        clients.forEach(client => {
            client.postMessage(data);
        });
    });
});
4. SharedWorker

SharedWorker 是一种 Web Worker,它允许多个浏览器上下文(如标签页、窗口或框架)共享同一个 Worker 实例。通过这种方式,多个标签页可以通过 SharedWorker 进行通信。

worker.js

js
const connections = [];

self.onconnect = function(event) {
    const port = event.ports[0];
    connections.push(port);

    port.onmessage = function(event) {
        const message = event.data;
        broadcast(message);
    };

    port.start();
};

function broadcast(message) {
    connections.forEach(connection => {
        connection.postMessage(message);
    });
}

主线程

js
const worker = new SharedWorker('shared-worker.js');

worker.port.onmessage = function(event) {
    const message = event.data;
    const messageElement = document.createElement('div');
    messageElement.textContent = message;
    document.getElementById('messages').appendChild(messageElement);
};

worker.port.start();

document.getElementById('send-button').addEventListener('click', function() {
    const message = document.getElementById('message-input').value;
    worker.port.postMessage(message);
});
5. PostMessage API

发送页面 (send.html)

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>PostMessage Send</title>
</head>
<body>
    <h2>发送数据到另一个标签页</h2>
    <input type="text" id="inputData" placeholder="输入数据">
    <button id="sendBtn">发送数据</button>
    <script>
        let otherWindow;

        // 打开第二个标签页
        document.getElementById('sendBtn').onclick = function() {
            const data = document.getElementById('inputData').value;
            if (!otherWindow || otherWindow.closed) {
                otherWindow = window.open('receive.html'); // 打开接收页面
            }
            // 发送数据到接收页面
            otherWindow.postMessage(data, '*');
            alert('数据已发送到另一个标签页!');
        };
    </script>
</body>
</html>

接收页面 (receive.html)

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>PostMessage Receive</title>
</head>
<body>
    <h2>接收 PostMessage 数据</h2>
    <script>
        window.addEventListener('message', function(event) {
            alert('接收到的数据: ' + event.data);
        });
    </script>
</body>
</html>