前端跨页面通信方法

实现不同页面间数据传递和通信的多种方案

问题

前端如何实现跨页面通信?

解答

1. LocalStorage / SessionStorage

通过 Web Storage API 在不同页面间共享数据,监听 storage 事件实现实时更新。

// 页面 A:写入数据
localStorage.setItem('message', JSON.stringify({ text: 'Hello' }));

// 页面 B:监听变化
window.addEventListener('storage', (e) => {
  if (e.key === 'message') {
    const data = JSON.parse(e.newValue);
    console.log('收到消息:', data.text);
  }
});

2. Cookies

在同一域名下的不同页面间传递数据。

// 设置 Cookie
document.cookie = 'user=John; path=/';

// 读取 Cookie
const cookies = document.cookie.split('; ').reduce((acc, item) => {
  const [key, value] = item.split('=');
  acc[key] = value;
  return acc;
}, {});

3. PostMessage

通过 window.postMessage() 在不同窗口间发送消息。

// 页面 A:发送消息
const targetWindow = window.open('https://example.com/page-b');
targetWindow.postMessage({ type: 'greeting', data: 'Hello' }, 'https://example.com');

// 页面 B:接收消息
window.addEventListener('message', (e) => {
  if (e.origin === 'https://example.com') {
    console.log('收到消息:', e.data);
  }
});

4. Broadcast Channel

在同一浏览器的不同上下文间进行双向通信。

// 页面 A:创建频道并发送
const channel = new BroadcastChannel('my_channel');
channel.postMessage({ text: 'Hello from A' });

// 页面 B:监听消息
const channel = new BroadcastChannel('my_channel');
channel.onmessage = (e) => {
  console.log('收到消息:', e.data.text);
};

5. SharedWorker

多个页面共享同一个 Worker 进行通信。

// shared-worker.js
const connections = [];
onconnect = (e) => {
  const port = e.ports[0];
  connections.push(port);
  port.onmessage = (e) => {
    connections.forEach(p => p.postMessage(e.data));
  };
};

// 页面使用
const worker = new SharedWorker('shared-worker.js');
worker.port.postMessage('Hello');
worker.port.onmessage = (e) => console.log(e.data);

6. IndexedDB

通过客户端数据库在不同页面间存储和共享数据。

// 页面 A:写入数据
const request = indexedDB.open('MyDB', 1);
request.onsuccess = (e) => {
  const db = e.target.result;
  const transaction = db.transaction(['messages'], 'readwrite');
  transaction.objectStore('messages').add({ id: 1, text: 'Hello' });
};

// 页面 B:读取数据
const request = indexedDB.open('MyDB', 1);
request.onsuccess = (e) => {
  const db = e.target.result;
  const transaction = db.transaction(['messages'], 'readonly');
  transaction.objectStore('messages').get(1).onsuccess = (e) => {
    console.log(e.target.result);
  };
};

7. WebSockets

通过服务器实现不同页面间的实时通信。

// 页面 A 和页面 B 都连接同一个 WebSocket
const ws = new WebSocket('wss://example.com/socket');

ws.onopen = () => {
  ws.send(JSON.stringify({ type: 'message', data: 'Hello' }));
};

ws.onmessage = (e) => {
  const message = JSON.parse(e.data);
  console.log('收到消息:', message.data);
};

关键点

  • LocalStorage 适合同源页面间的简单数据共享,需监听 storage 事件
  • PostMessage 可跨域通信,但需要明确指定目标 origin 确保安全
  • Broadcast Channel 提供发布-订阅模式,适合同浏览器多标签页通信
  • SharedWorker 和 IndexedDB 适合需要共享状态或持久化数据的场景
  • WebSockets 需要服务器支持,适合需要实时双向通信的复杂场景