目录
扫描二维码关注公众号,回复:
17645209 查看本文章

1、BroadCast Channel
1、创建文件sender.html
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>发送消息</title> </head> <body> <h1>发送消息</h1> <input type="text" id="messageInput" placeholder="输入消息" /> <button id="sendButton">发送消息</button> <script> const channel = new BroadcastChannel('my_channel') document.getElementById('sendButton').addEventListener('click', () => { const message = document.getElementById('messageInput').value channel.postMessage({ message }) }) </script> </body> </html>
2、创建文件receiver.html
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>接收消息</title> </head> <body> <h1>接收消息</h1> <div id="messageDiv"></div> <script> const messageDiv = document.getElementById('messageDiv') const channel = new BroadcastChannel('my_channel') channel.onmessage = event => { messageDiv.innerHTML += `<p>收到消息: ${event.data.message}</p>` } </script> </body> </html>
2、Service Worker
1、创建文件sender.html
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>发送消息</title> </head> <body> <h1>发送消息</h1> <input type="text" id="messageInput" placeholder="输入消息" /> <button id="sendButton">发送消息</button> <script> if ('serviceWorker' in navigator) { navigator.serviceWorker .register('service-worker.js') .then(() => { console.log('Service Worker 注册成功') }) .catch(error => { console.error('Service Worker 注册失败:', error) }) } document.getElementById('sendButton').addEventListener('click', () => { const message = document.getElementById('messageInput').value navigator.serviceWorker.controller.postMessage({ message }) }) </script> </body> </html>
2、创建文件receiver.html
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>接收消息</title> </head> <body> <h1>接收消息</h1> <div id="messageDiv"></div> <script> const messageDiv = document.getElementById('messageDiv') if ('serviceWorker' in navigator) { navigator.serviceWorker .register('service-worker.js') .then(() => { console.log('Service Worker 注册成功') }) .catch(error => { console.error('Service Worker 注册失败:', error) }) navigator.serviceWorker.onmessage = event => { messageDiv.innerHTML += `<p>收到消息: ${event.data.message}</p>` } } </script> </body> </html>
3、创建文件service-worker.js
self.addEventListener('message', event => { const message = event.data.message // 将消息转发给所有客户端 self.clients.matchAll().then(clients => { clients.forEach(client => { client.postMessage({ message }) }) }) })
3、LocalStorage
1、创建文件sender.html
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>发送消息</title> </head> <body> <h1>发送消息</h1> <input type="text" id="messageInput" placeholder="输入消息" /> <button id="sendButton">发送消息</button> <script> document.getElementById('sendButton').addEventListener('click', () => { const message = document.getElementById('messageInput').value localStorage.setItem('message', message) }) </script> </body> </html>
2、创建文件receiver.html
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>接收消息</title> </head> <body> <h1>接收消息</h1> <div id="messageDiv"></div> <script> const messageDiv = document.getElementById('messageDiv') // 处理存储事件 window.addEventListener('storage', event => { if (event.key === 'message') { messageDiv.innerHTML += `<p>收到消息: ${event.newValue}</p>` } }) // 如果页面加载时有消息,立即显示 const initialMessage = localStorage.getItem('message') if (initialMessage) { messageDiv.innerHTML += `<p>收到消息: ${initialMessage}</p>` } </script> </body> </html>
4、Shared Worker
1、创建文件sender.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>发送消息</title> </head> <body> <h1>发送消息</h1> <input type="text" id="message" placeholder="输入消息" /> <button id="send">发送消息</button> <script> const worker = new SharedWorker('./sharedWorker.js') const messageInput = document.getElementById('message') const sendButton = document.getElementById('send') // 发送消息 sendButton.onclick = () => { const message = messageInput.value if (message) { worker.port.postMessage(message) messageInput.value = '' } } worker.port.start() </script> </body> </html>
2、创建文件receiver.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>接收消息</title> </head> <body> <h1>接收消息</h1> <div id="messages"></div> <script> const worker = new SharedWorker('sharedWorker.js') const messagesDiv = document.getElementById('messages') // 接收消息 worker.port.onmessage = event => { messagesDiv.innerHTML += `<p>收到消息: ${event.data}</p>` } worker.port.start() </script> </body> </html>
3、创建文件shared-worker.js
// sharedWorker.js let connections = [] onconnect = function (e) { const port = e.ports[0] connections.push(port) port.onmessage = function (event) { // 广播接收到的消息给所有连接的端口 connections.forEach(conn => { if (conn !== port) { conn.postMessage(event.data) } }) } port.start() }
5、IndexedDB
1、创建文件sender.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>发送消息</title> </head> <body> <h1>发送消息</h1> <input type="text" id="message" placeholder="输入消息" /> <button id="send">发送消息</button> <script> const dbName = 'messageDB' let db // 打开数据库 const request = indexedDB.open(dbName, 1) request.onupgradeneeded = event => { db = event.target.result db.createObjectStore('messages', { keyPath: 'id', autoIncrement: true }) } request.onsuccess = event => { db = event.target.result } // 发送消息 document.getElementById('send').onclick = () => { const message = document.getElementById('message').value if (message) { const transaction = db.transaction('messages', 'readwrite') const store = transaction.objectStore('messages') store.add({ content: message }) document.getElementById('message').value = '' } } </script> </body> </html>
2、创建文件receiver.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>接收消息</title> </head> <body> <h1>接收消息</h1> <div id="messages"></div> <script> const dbName = 'messageDB' let db // 打开数据库 const request = indexedDB.open(dbName, 1) request.onupgradeneeded = event => { db = event.target.result db.createObjectStore('messages', { keyPath: 'id', autoIncrement: true }) } request.onsuccess = event => { db = event.target.result fetchMessages() setInterval(fetchMessages, 2000) // 每2秒检查一次新消息 } // 获取消息 function fetchMessages() { const transaction = db.transaction('messages', 'readonly') const store = transaction.objectStore('messages') const request = store.getAll() request.onsuccess = event => { const messages = event.target.result const messagesDiv = document.getElementById('messages') messagesDiv.innerHTML = '' // 清空之前的消息 messages.forEach(msg => { const messageElement = document.createElement('div') messageElement.textContent = `收到消息: ${msg.content}` messagesDiv.appendChild(messageElement) }) } } </script> </body> </html>
6、Cookie
1、创建文件sender.html
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>发送消息</title> </head> <body> <h1>发送消息</h1> <input type="text" id="message" placeholder="输入消息" /> <button id="send">发送消息</button> <script> // 设置 Cookie function setCookie(name, value, days) { const d = new Date() d.setTime(d.getTime() + days * 24 * 60 * 60 * 1000) const expires = 'expires=' + d.toUTCString() document.cookie = name + '=' + value + ';' + expires + ';path=/' } // 发送消息 document.getElementById('send').onclick = () => { const message = document.getElementById('message').value if (message) { setCookie('message', message, 1) // 存储消息到 Cookie document.getElementById('message').value = '' } } </script> </body> </html>
2、创建文件receiver.html
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>接收消息</title> </head> <body> <h1>接收消息</h1> <div id="messages"></div> <script> // 读取 Cookie function getCookie(name) { const value = `; ${document.cookie}` const parts = value.split(`; ${name}=`) if (parts.length === 2) return parts.pop().split(';').shift() } // 显示消息 function displayMessage() { const message = getCookie('message') const messagesDiv = document.getElementById('messages') messagesDiv.innerHTML = '' // 清空之前的消息 if (message) { const messageElement = document.createElement('div') messageElement.textContent = `接收到: ${message}` messagesDiv.appendChild(messageElement) // 清除消息,避免重复显示 document.cookie = 'message=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;' } } // 每2秒检查一次新消息 setInterval(displayMessage, 2000) </script> </body> </html>
7、Window
1、创建文件sender.html
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>发送消息</title> </head> <body> <h1>发送消息</h1> <input type="text" id="message" placeholder="输入消息" /> <button id="send">发送消息</button> <script> let receiverWindow // 打开接收消息的窗口 function openReceiver() { if (!receiverWindow || receiverWindow.closed) { receiverWindow = window.open('receiver.html', 'ReceiverWindow') // 在接收窗口加载完成后,设置监听器 receiverWindow.onload = () => { const message = document.getElementById('message').value if (message) { receiverWindow.postMessage(message, '*') // 发送消息 } } } else { receiverWindow.focus() } } // 发送消息 document.getElementById('send').onclick = () => { const message = document.getElementById('message').value openReceiver() // 确保接收窗口打开 // 如果窗口已打开且不为空,发送消息 if (receiverWindow && message) { receiverWindow.postMessage(message, '*') // 发送消息 document.getElementById('message').value = '' // 清空输入框 } } </script> </body> </html>
2、创建文件receiver.html
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>接收消息</title> </head> <body> <h1>接收消息</h1> <div id="messages"></div> <script> // 接收消息 window.addEventListener('message', event => { const messagesDiv = document.getElementById('messages') const messageElement = document.createElement('div') messageElement.textContent = `接收到: ${event.data}` messagesDiv.appendChild(messageElement) }) </script> </body> </html>
8、Websocket
1、创建文件sender.html
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>发送消息</title> </head> <body> <h1>发送消息</h1> <input type="text" id="message" placeholder="输入消息" /> <button id="send">发送消息</button> <script> const socket = new WebSocket('ws://localhost:8080') // 发送消息 document.getElementById('send').onclick = () => { const message = document.getElementById('message').value if (message) { socket.send(message) // 发送消息 document.getElementById('message').value = '' // 清空输入框 } } </script> </body> </html>
2、创建文件receiver.html
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>接收消息</title> </head> <body> <h1>接收消息</h1> <div id="messages"></div> <script> const socket = new WebSocket('ws://localhost:8080') // 接收消息 socket.onmessage = event => { console.log(event) const messagesDiv = document.getElementById('messages') const messageElement = document.createElement('div') messageElement.textContent = `接收到: ${event.data}` messagesDiv.appendChild(messageElement) } </script> </body> </html>
3、创建文件server.js
const WebSocket = require('ws') const wss = new WebSocket.Server({ port: 8080 }) wss.on('connection', ws => { console.log('新客户端连接') ws.on('message', message => { console.log(`收到消息: ${message}`) // 广播给所有连接的客户端 wss.clients.forEach(client => { if (client.readyState === WebSocket.OPEN) { client.send(message.toString()) } }) }) ws.on('close', () => { console.log('客户端断开连接') }) }) console.log('WebSocket 服务器正在运行,监听端口 8080')
4、运行服务器:
npm install ws node server.js
总结:
1. Broadcast Channel
- 优点:
- 简单易用,API 直观。
- 支持多个标签页间的实时通信。
- 可以发送任意类型的消息(字符串、对象等)。
- 缺点:
- 数据传递是基于消息的,可能会有延迟。
- 不适合大量数据传输。
- 需要支持的浏览器较新,兼容性可能有限。
2. Service Worker
- 优点:
- 支持离线操作,可以在网络断开时继续工作。
- 能够拦截网络请求,提供更大的灵活性。
- 可以用于后台处理和数据缓存。
- 缺点:
- 配置和实现相对复杂。
- 不能直接访问 DOM,使用场景有限。
- 需要注册和管理生命周期。
3. LocalStorage
- 优点:
- 简单易用,支持持久化存储。
- 在同一源(origin)下,所有标签页共享相同的数据。
- 缺点:
- 同步方式,可能会有数据更新延迟。
- 存储容量有限(通常为 5MB)。
- 不支持跨源数据共享。
4. Shared Worker
- 优点:
- 可以被多个标签页和窗口共享,适合复杂应用。
- 允许更高效的数据共享与通信。
- 缺点:
- 实现较复杂,需要理解 worker 的生命周期。
- 需要支持的浏览器较新。
- 有时会受到同源政策的限制。
5. IndexedDB
- 优点:
- 支持大规模数据存储(数百 MB 甚至更多)。
- 结构化数据存储,支持复杂查询。
- 异步操作,不会阻塞主线程。
- 缺点:
- API 较复杂,上手难度较高。
- 需要考虑数据库版本控制和事务处理。
- 数据可能需要在不同标签页间进行同步。
6. Cookie
- 优点:
- 兼容性好,几乎所有浏览器都支持。
- 可以设置过期时间,适合需要持久化的简单数据。
- 缺点:
- 数据容量有限(通常为 4KB)。
- 频繁的网络请求可能导致性能问题。
- 安全性较低,容易受到 CSRF 攻击。
7. Window
- 优点:
- 可以直接访问浏览器窗口和标签页,适合简单的数据传递。
- 在同一源的标签页间可以直接通过
window.opener
或window.name
共享数据。
- 缺点:
- 不适合复杂的数据共享,限制较多。
- 依赖于窗口的打开方式,局限性大。
- 难以管理多个标签页间的数据状态。
8. WebSocket
- 优点:
- 实时双向通信,适合需要快速响应的数据共享。
- 适合大规模和高频率的数据传输。
- 缺点:
- 需要服务器支持,增加了实现的复杂性。
- 可能涉及更多的安全性和连接管理问题。
- 不适合简单的数据共享,通常用于更复杂的应用场景。