目录
1、BroadCast Channel
2、Service Worker
3、LocalStorage
4、Shared Worker
5、IndexedDB
6、Cookie
7、Window
8、Websocket
总结:
1、BroadCast Channel
1、创建文件sender.html
发送消息
const channel = new BroadcastChannel('my_channel')
document.getElementById('sendButton').addEventListener('click', () => {
const message = document.getElementById('messageInput').value
channel.postMessage({ message })
})
2、创建文件receiver.html
接收消息
const messageDiv = document.getElementById('messageDiv')
const channel = new BroadcastChannel('my_channel')
channel.onmessage = event => {
messageDiv.innerHTML += `
收到消息: ${event.data.message}
`}
2、Service Worker
1、创建文件sender.html
发送消息
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 })
})
2、创建文件receiver.html
接收消息
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 += `
收到消息: ${event.data.message}
`}
}
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
发送消息
document.getElementById('sendButton').addEventListener('click', () => {
const message = document.getElementById('messageInput').value
localStorage.setItem('message', message)
})
2、创建文件receiver.html
接收消息
const messageDiv = document.getElementById('messageDiv')
// 处理存储事件
window.addEventListener('storage', event => {
if (event.key === 'message') {
messageDiv.innerHTML += `
收到消息: ${event.newValue}
`}
})
// 如果页面加载时有消息,立即显示
const initialMessage = localStorage.getItem('message')
if (initialMessage) {
messageDiv.innerHTML += `
收到消息: ${initialMessage}
`}
4、Shared Worker
1、创建文件sender.html
发送消息
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()
2、创建文件receiver.html
接收消息
const worker = new SharedWorker('sharedWorker.js')
const messagesDiv = document.getElementById('messages')
// 接收消息
worker.port.onmessage = event => {
messagesDiv.innerHTML += `
收到消息: ${event.data}
`}
worker.port.start()
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
发送消息
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 = ''
}
}
2、创建文件receiver.html
接收消息
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)
})
}
}
6、Cookie
1、创建文件sender.html
发送消息
// 设置 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 = ''
}
}
2、创建文件receiver.html
接收消息
// 读取 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)
7、Window
1、创建文件sender.html
发送消息
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 = '' // 清空输入框
}
}
2、创建文件receiver.html
接收消息
// 接收消息
window.addEventListener('message', event => {
const messagesDiv = document.getElementById('messages')
const messageElement = document.createElement('div')
messageElement.textContent = `接收到: ${event.data}`
messagesDiv.appendChild(messageElement)
})
8、Websocket
1、创建文件sender.html
发送消息
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 = '' // 清空输入框
}
}
2、创建文件receiver.html
接收消息
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)
}
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
优点:
实时双向通信,适合需要快速响应的数据共享。适合大规模和高频率的数据传输。缺点:
需要服务器支持,增加了实现的复杂性。可能涉及更多的安全性和连接管理问题。不适合简单的数据共享,通常用于更复杂的应用场景。