前言
最近都在和浏览器存储打交道,不可避免的知道了一个新的存储方式IndexDB。
介绍
IndexedDB 是浏览器内置的一个非关系型数据库,和 localStorage 不同,它可以存储大量结构化数据(包括文件和二进制数据),并且支持索引查询和事务操作。单个域名的存储上限通常在几百 MB 到几 GB,远比 localStorage 的 5MB 大得多。
常见浏览器存储方案对比:
| 方案 | 容量 | 类型 | 适用场景 |
|---|---|---|---|
| localStorage | ~5MB | 字符串 | 小量配置、token |
| sessionStorage | ~5MB | 字符串 | 会话级临时数据 |
| Cookie | 4KB | 字符串 | 身份标识 |
| Cache API | 较大 | Request/Response | 离线缓存 |
| IndexedDB | 数百MB~GB | 任意结构化数据 | 大量数据、文件存储 |
为什么用 IndexedDB 处理大文件下载
下载大文件(比如几百 MB 的视频、压缩包)时,传统方式会遇到几个问题:
- 内存爆炸:如果把整个文件存在内存中(Blob),大文件会直接撑爆内存,页面卡死甚至崩溃
- 无法断点续传:浏览器默认下载一旦中断就要重来,用户体验很差
- 无法持久化:刷新页面后内存中的数据就没了
IndexedDB 恰好能解决这些问题:
- 数据存在磁盘上,不占用内存
- 支持事务操作,可以随时写入、读取部分数据
- 持久化存储,刷新页面不会丢失
实现思路
核心思路很简单:分块下载 + 逐块写入 IndexedDB + 最后合并导出。
整个流程分为四步:
- 初始化数据库:创建 IndexedDB 数据库和对象存储
- 分块下载:通过 HTTP Range 请求,每次下载固定大小的数据块
- 逐块写入:每下载完一个块,立即写入 IndexedDB
- 合并导出:所有块下载完成后,从 IndexedDB 读取并合并成完整文件,触发浏览器下载
结语
IndexedDB 处理大文件下载的核心优势就是不占内存 + 持久化 + 支持断点续传。相比传统方式,它让大文件下载在浏览器端变得可控且稳定。
完整流程总结:HEAD 请求获取大小 → Range 分块下载 → 逐块写入 IndexedDB → 合并 Blob 导出。这个思路同样适用于大文件上传,只不过是将”下载”换成”读取文件分片 + 上传分片”。
但是缺点也很明显,就是需要等待所有块下载完成后,才能合并导出文件。