IndexedDB 是浏览器端适合音乐类应用的本地数据库,支持事务、索引与 Blob 存储,需分 playlists 和 downloads 仓库管理,通过版本升级、事务写入、索引查询及错误降级保障离线播放可靠性。

IndexedDB 是浏览器端强大的本地数据库,适合存储结构化数据,比如音乐播放列表和下载状态。它支持事务、索引、大容量二进制数据(如音频文件 Blob),且能离线工作,非常适合音乐类应用的缓存需求。
初始化数据库并创建对象仓库
首次打开数据库时需定义版本与结构。播放列表和下载状态建议分两个对象仓库管理,便于独立读写与更新。
- 使用 indexedDB.open("musicDB", 2) 打开或升级数据库(版本号递增触发 upgrade 事件)
- 在 onupgradeneeded 中创建
playlists仓库(主键为 playlistId),添加索引如userId方便按用户查询 - 同时创建 downloads 仓库(主键为 trackId),添加
status("pending"/"completed"/"failed")和file(Blob 类型,可存音频文件或仅 URL)字段 - 注意:Blob 可直接存入 IndexedDB,但需确保在同源上下文中创建(避免跨域 Blob 导致序列化失败)
保存与更新播放列表
播放列表通常包含 id、name、trackIds 数组、更新时间等字段。写入时推荐使用事务保证一致性。
- 调用 db.transaction(["playlists"], "readwrite") 获取仓库
- 用 store.put({id: "pl_123", name: "我的最爱", trackIds: ["t1","t2"], updatedAt: Date.now()}) 写入或覆盖
- 若需批量更新多个列表,可在同一事务中多次调用 put,避免频繁开闭事务
- 查询时可用 store.index("userId").getAll(ID) 快速获取某用户所有列表
管理单曲下载状态与缓存音频文件
下载状态需实时反映进度与结果;已下载音频应尽量缓存为 Blob,减少重复请求。
- 开始下载前先写入初始状态:downloads.put({trackId: "t1", status: "pending", progress: 0})
- 下载完成时更新为
{status: "completed", file: blob, size: blob.size, downloadedAt: Date.now()} - 播放时优先从 downloads.get("t1") 读取 Blob,用 URL.createObjectURL(blob) 创建可播放的 src
- 注意:createObjectURL 生成的 URL 需手动 revoke(如页面卸载或切换歌曲后),否则内存泄漏
错误处理与降级策略
IndexedDB 操作可能失败(如用户禁用、磁盘满、版本冲突),需有兜底逻辑。
- 所有请求监听 onsuccess / onerror,失败时记录日志并 fallback 到内存 Map 或 localStorage(仅存轻量元数据)
- 对大文件下载,可先存 metadata 到 IndexedDB,再将 Blob 分块写入(用
put()分多次提交,避免单次过大阻塞) - 监听 blocked 事件,提示用户关闭其他标签页以完成数据库升级
- 定期清理过期下载项(如 30 天未使用),用游标遍历 + 条件删除
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











