localstorage无统一固定容量,实际因浏览器而异:chrome/edge约10mb、firefox约5–10mb、ios safari常低于5mb且受内存压力动态压缩;超限时setitem()抛quotaexceedederror。

localStorage 没有统一、固定的容量上限,实际可用空间取决于浏览器、设备类型、隐私模式和系统状态——Chrome 桌面通常约 10 MB,Firefox 约 5–10 MB,iOS Safari 常低于 5 MB(低内存时可能骤降至 0),Edge 最高可达 10 MB;但这些数字只是启发式配额,不是硬保障。
为什么“5MB”说法不靠谱
这个数字来自早期 HTML5 规范建议值,但现代浏览器早已脱离该限制:Chrome 自 v80 起默认按源分配约 10 MB,Safari 在 macOS 17+ 升至 5 MB,但 iOS 上仍受内存压力动态压缩;更关键的是,它不反映真实字节占用——localStorage.setItem() 计费单位是 UTF-16 编码后的字符长度("?".length === 1),而底层存储按 UTF-8 字节算("?" 占 4 字节)。直接用 String.length 估算必然高估可用空间。
怎么知道当前还能写多少
浏览器不提供 localStorage.remainingSpace 这类 API,只能靠组合策略逼近:
- 用
new TextEncoder().encode(str).length算待存数据的真实 UTF-8 字节数,比JSON.stringify(obj).length可靠得多 - 维护一个本地计数器(如
localStorage.__sizeEstimate),每次setItem()前加权累加,removeItem()后扣减(注意:需手动管理,不自动同步) - 试探性写入:先
localStorage.setItem('probe', 'x'),成功后立刻localStorage.removeItem('probe'),这是最轻量的“是否可写”探路方式 - 别信
localStorage.length或遍历所有 key 来推算——它们只返回项数,不反映字节总量
超限时会发生什么
setItem() 不会静默失败,但错误表现不一致:
- 主流浏览器抛
DOMException: QuotaExceededError - iOS Safari 隐私模式可能直接禁用
localStorage,此时抛SecurityError - 旧版 Safari 曾返回
SyntaxError,部分 Android WebView 甚至不报错,只截断字符串 - 错误只在写入瞬间触发,无法提前预警;且一旦发生,后续 JS 执行可能中断(尤其在无 try/catch 的循环中)
真正需要存大容量数据时怎么办
别在 localStorage 上硬扛:
- 超过 100 KB 的单条结构化数据(如用户文档、日志数组),优先用
indexedDB:异步、支持事务、配额可达空闲磁盘的 50–60% - 写入前对字符串做轻量压缩(如
pako.deflate+TextEncoder),中文内容常能压缩掉 60%+ - 超 16 MB 的单条记录必须分片(
blobId_0,blobId_1…),否则 Chrome 会拒绝写入 - 降级链要真实可用:当
indexedDB.open()失败时,fallback 到sessionStorage或内存Map,而不是再试一次localStorage
最麻烦的不是数字本身,而是同一份代码在 Chrome 桌面能跑,在微信 X5 内核下实测不到 1 MB 就崩——关键逻辑不能假设“刚存的值下秒还在”,尤其是移动端后台标签页里,Safari 会主动清理。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











