前言
之前介绍的前端跨页面通讯方案中,每种都有各自的应用场景。今天要介绍一种,当面临大量数据存储需求时,也是一个不错的选择。它就是--IndexedDB。
本文将介绍IndexedDB跨页面通讯,基础用法请参考IndexedDB 使用指南。
1. 什么是IndexedDB ?
IndexedDB是浏览器提供的本地数据库解决方案。
特点有:
- 大容量存储:存储上限远高于localStorage(通常为浏览器磁盘空间的一定比例,GB级别),可存储大量结构化数据、二进制数据(图片、文件等)。
- 同源共享:同一域名下的所有页面(包括不同标签页、窗口)可共享同一个IndexedDB数据库,为跨页面通讯提供基础。
- 异步操作:所有操作(打开、读写、删除)均为异步,避免阻塞主线程,保障页面流畅性。
- 事务支持:基于事务(transaction)执行操作,确保数据一致性,支持失败回滚。
- 索引优化:可创建索引加速数据查询,解决大量数据下的查询性能问题。
IndexedDB更适合需存储大量数据、追求实时通讯且不阻塞页面的跨页面场景。
2. 案例代码
IndexedDB无原生跨页面事件,核心通过"数据库存储+变化监听"实现同步方式实现。
2.1 父子通讯
主页面向 iframe 子页面发送消息。
实现方式:
- 主页面和 iframe 子页面共享同一个 indexDB 数据库
- 主页面向 indexDB 添加消息,包含 sender 标识为 'parent'
- 主页面通过 localStorage 的 storage 事件通知其他页面
- 子页面监听 storage 事件,收到通知后重新加载消息列表
- 子页面根据 sender 标识识别出这是父子通讯
核心代码实现:
ini
// 父页面发送消息
function sendToChild(content) {
const message = {
content: content,
sender: 'parent', // 标识为父页面
timestamp: Date.now()
};
// 写入 IndexedDB
const transaction = db.transaction(['messages'], 'readwrite');
const store = transaction.objectStore('messages');
store.add(message);
// 触发 storage 事件通知所有子页面
localStorage.setItem('indexDBUpdate', Date.now().toString());
}
// 子页面接收消息
window.addEventListener('storage', (event) => {
if (event.key === 'indexDBUpdate') {
// 重新加载消息,筛选出 sender === 'parent' 的消息
loadMessages().then(messages => {
const parentMessages = messages.filter(m => m.sender === 'parent');
displayMessages(parentMessages, '父子通讯');
});
}
});

2.2 子父通讯
iframe 子页面向主页面发送消息。
实现方式:
- iframe 子页面和主页面共享同一个 indexDB 数据库
- 子页面向 indexDB 添加消息,包含 sender 标识为 'child_1' 或 'child_2'
- 子页面通过 localStorage 的 storage 事件通知其他页面
- 主页面监听 storage 事件,收到通知后重新加载消息列表
- 主页面根据 sender 标识识别出这是子父通讯
核心代码实现:
javascript
// 子页面发送消息
function sendToParent(content) {
const message = {
content: content,
sender: 'child_1', // 标识为子页面
timestamp: Date.now()
};
// 写入 IndexedDB
const transaction = db.transaction(['messages'], 'readwrite');
const store = transaction.objectStore('messages');
store.add(message);
// 触发 storage 事件通知父页面
localStorage.setItem('indexDBUpdate', Date.now().toString());
}
// 父页面接收消息
window.addEventListener('storage', (event) => {
if (event.key === 'indexDBUpdate') {
// 重新加载消息,筛选出所有子页面的消息
loadMessages().then(messages => {
const childMessages = messages.filter(m => m.sender.startsWith('child_'));
displayMessages(childMessages, '子父通讯');
});
}
});
2.3 兄弟通讯
一个 iframe 子页面向另一个 iframe 子页面发送消息。
实现方式:
- 多个 iframe 子页面共享同一个 indexDB 数据库
- 一个子页面向 indexDB 添加消息,包含 sender 标识为 'child_1' 或 'child_2'
- 该子页面通过 localStorage 的 storage 事件通知其他页面
- 其他子页面监听 storage 事件,收到通知后重新加载消息列表
- 其他子页面根据 sender 标识识别出这是兄弟通讯
核心代码实现:
javascript
// 子页面1发送消息给子页面2
function sendToSibling(content) {
const message = {
content: content,
sender: 'child_1', // 发送者标识
timestamp: Date.now()
};
// 写入 IndexedDB
const transaction = db.transaction(['messages'], 'readwrite');
const store = transaction.objectStore('messages');
store.add(message);
// 触发 storage 事件通知其他页面
localStorage.setItem('indexDBUpdate', Date.now().toString());
}
// 子页面2接收消息
const currentChildId = 'child_2'; // 当前页面标识
window.addEventListener('storage', (event) => {
if (event.key === 'indexDBUpdate') {
// 重新加载消息,筛选出其他子页面的消息
loadMessages().then(messages => {
const siblingMessages = messages.filter(m =>
m.sender.startsWith('child_') && m.sender !== currentChildId
);
displayMessages(siblingMessages, '兄弟通讯');
});
}
});

3. 总结
最后总结一下:IndexedDB凭借同源共享、大容量存储与异步无阻塞特性,是跨页面大数据通讯的不二选择,适配多标签、iframe等复杂场景。