← 返回题目列表

IndexedDB 和 localStorage 有什么区别?适合存什么数据?

高频 中等 第 10 / 30 题 更新于 2026/07/29
浏览器存储IndexedDBlocalStorage离线

简化版

IndexedDB 是浏览器内置的异步事务型客户端数据库,适合存大量结构化数据、离线数据和索引查询;localStorage 是同步键值存储,容量小、会阻塞主线程,适合少量简单配置。大数据、离线缓存和复杂查询优先 IndexedDB。

详细版

对比:

  • localStorage:同步 API,字符串键值,简单但容量和性能有限。
  • IndexedDB:异步 API,支持对象仓库、索引、事务、游标,容量更大。
  • Cache Storage:更适合缓存 Request/Response,不适合业务结构化查询。

IndexedDB 常见场景:

  • 离线表单草稿。
  • 大列表、本地搜索索引。
  • PWA 离线数据。
  • 图片、文件、二进制 Blob。
  • 客户端缓存接口结果。

面试回答要强调:IndexedDB 不应存敏感明文数据,浏览器端存储都不能当安全边界。

完整版教学

一、为什么 localStorage 不够用

localStorage API 简单,但它是同步的,并且只能存字符串。少量配置很方便,数据一大就会阻塞主线程。

localStorage.setItem('theme', 'dark')
const theme = localStorage.getItem('theme')

如果把 5MB JSON 字符串写入 localStorage,序列化、写入和读取解析都可能卡住页面。它也没有索引能力,想按条件查询只能整体取出再遍历。

IndexedDB 解决的是更复杂的客户端存储问题:数据量更大、读写异步、支持事务和索引,更接近浏览器里的轻量数据库。

二、IndexedDB 的核心概念

IndexedDB 里有数据库、版本、对象仓库、索引和事务。对象仓库类似表,索引类似查询加速结构,事务保证一组操作的边界。

Database: app-db
  -> ObjectStore: orders
     -> keyPath: id
     -> Index: by_status
     -> Index: by_update_time

例如订单离线缓存中,可以用 orders 仓库存订单对象,用 status 建索引快速查待同步订单,用 updatedAt 建索引按时间清理。

概念类比作用
database数据库存储命名空间
object store存对象
index索引加速查询
transaction事务控制读写一致性

三、IndexedDB 是异步和事件驱动的

原生 IndexedDB API 偏事件风格,使用起来比 localStorage 复杂。很多项目会使用轻量封装库来把它 Promise 化。

const request = indexedDB.open('app-db', 1)

request.onupgradeneeded = () => {
  const db = request.result
  const store = db.createObjectStore('notes', { keyPath: 'id' })
  store.createIndex('by_updated', 'updatedAt')
}

request.onsuccess = () => {
  const db = request.result
  const tx = db.transaction('notes', 'readwrite')
  tx.objectStore('notes').put({ id: 1, text: 'hello', updatedAt: Date.now() })
}

版本升级时,结构变更要写在 onupgradeneeded 中。比如从 v1 升到 v2 时新增索引,老用户打开页面才会触发迁移。

这也是 IndexedDB 的工程难点:不仅要会读写,还要设计版本迁移。

四、事务决定读写边界

IndexedDB 的读写发生在事务中。事务有只读和读写模式,读写事务完成前,一组操作可以作为一个边界提交或失败。

transaction(readwrite)
  -> put order
  -> put syncTask
  -> complete

假设用户离线创建订单草稿,你需要同时写入 draftssyncTasks。如果只写了草稿但没写同步任务,用户联网后就不会上传;事务能帮助这类状态保持一致。

当然 IndexedDB 不是后端数据库,不能承担跨设备一致性,也不能代替服务端事务。它解决的是单浏览器客户端本地数据一致性。

五、IndexedDB 适合大数据和离线场景

IndexedDB 常用于 PWA、离线编辑器、本地搜索、地图瓦片、图片 Blob、表单草稿和接口缓存。它能存对象和二进制数据,比 localStorage 更适合业务数据。

数字例子:一个客服系统要缓存最近 10000 条会话,每条 2KB,总计约 20MB。localStorage 不适合;IndexedDB 可以分对象存储,并按会话 id、更新时间建立索引。

适合 IndexedDB:
大量结构化数据
按索引查询
离线可编辑
二进制 Blob

适合 localStorage:
主题、语言、少量开关

如果只是保存一个 theme=dark,用 IndexedDB 就太重;如果是离线表单队列,用 localStorage 就太弱。

六、容量、安全和清理策略

浏览器存储空间不是无限的,用户、浏览器和系统都可能清理站点数据。IndexedDB 容量通常比 localStorage 大,但仍要设计清理策略。

清理策略:
1. 按时间淘汰旧缓存
2. 按业务状态删除已同步数据
3. 控制 Blob 和图片大小
4. 提供用户清理入口

安全上,IndexedDB 存在客户端,用户可清理,也可能被 XSS 脚本读取。因此不要存明文密码、长期敏感 token、私钥等高敏感数据。如果必须存业务数据,要做最小化、过期和服务端校验。

记忆钩子:IndexedDB 是“离线数据库”,不是“安全保险箱”。能存很多,不代表什么都该存。

七、常见误区与追问

  • 误区:IndexedDB 只是更大的 localStorage。 它是异步事务型对象数据库,支持对象仓库、索引和事务。
  • 误区:localStorage 简单,所以可以存所有缓存。 它同步阻塞主线程,数据大时会造成卡顿。
  • 误区:IndexedDB 中的数据很安全。 XSS 仍可能读取客户端数据,敏感信息不能明文长期存放。
  • 追问:IndexedDB 和 Cache Storage 怎么选? 结构化业务数据用 IndexedDB,请求响应资源缓存用 Cache Storage。
  • 追问:版本升级怎么做?onupgradeneeded 中创建仓库、索引或迁移数据。
  • 追问:离线编辑为什么适合 IndexedDB? 它能存大量结构化草稿和同步队列,并用事务保持本地状态一致。

八、加强记忆

IndexedDB 题按“异步、大量、结构化、事务、离线”记:localStorage 是同步小键值,IndexedDB 是异步本地数据库。小配置用 localStorage,大数据和离线队列用 IndexedDB;安全上永远记住客户端存储不是可信边界。