华韵 發表於 2025-8-11 10:38:00

Web前端入门第 83 问:JavaScript localStorage 有大小限制吗?溢出会怎样?

<p>本地存储除了 Cookie 外,还有 <code>localStorage</code> 和 <code>sessionStorage</code>,本文一探 <code>localStorage</code>。</p>
<h2 id="localstorage">localStorage</h2>
<p>此 API 存入的数据会 <code>永久</code> 保存在浏览器中,除非用户手动删除。</p>
<p><code>localStorage</code> 能用于<strong>同一</strong>浏览器<strong>同一</strong>域名跨标签页通信。</p>
<p>同一浏览器<strong>无痕模式</strong>和<strong>非无痕模式</strong>下,<code>localStorage</code> 存储的数据无法互通,且无痕模式存入的数据在浏览器关闭时候会被清除(所有无痕模式窗口关闭也会清除)!!</p>
<h3 id="api">API</h3>
<p>localStorage 对象暴露的 API 很简单,就几个增删改操作方法:</p>
<pre><code class="language-js">// 只读属性,返回本地存储项的数目
localStorage.length

// 获取本地存储的第 n 个键名
localStorage.key(n)
// 获取本地存储的值
localStorage.getItem(key)
// 写入本地存储
localStorage.setItem(key, value)
// 删除本地存储
localStorage.removeItem(key)
// 清空所有本地存储
localStorage.clear()
</code></pre>
<p>示例:</p>
<pre><code class="language-js">(() =&gt; {
// 监听 storage 事件
window.addEventListener('storage', e =&gt; {
    // 本页面不会触发 storage 事件
    // 需要新开一个 tab 查看变化
    console.log(e);
})

// 写入数据
localStorage.setItem('type', '公众号');
localStorage.setItem('name', '前端路引');

// 获取本地存储长度
console.log(localStorage.length);

// 循环打印本地存储
for (let i = 0; i &lt; localStorage.length; i++) {
    const key = localStorage.key(i);
    const value = localStorage.getItem(key);
    console.log(`${key}: ${value}`);
}
// 移除单个本地存储
localStorage.removeItem('name');
// 移除所有本地存储
localStorage.clear();
})()
</code></pre>
<p>以上代码中的 storage 事件只会在有<strong>多个标签页</strong>打开的情况下,才会触发;只有一个窗口时, <code>localStorage</code> 的改变并不会触发 storage 事件。</p>
<p>MDN 中有这么一句话:</p>
<p><img src="https://img2024.cnblogs.com/blog/596097/202508/596097-20250811103524633-1179701116.png"></p>
<p>原文:https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API</p>
<p>上面代码执行结果:</p>
<p><img src="https://img2024.cnblogs.com/blog/596097/202508/596097-20250811103529184-289190390.png"></p>
<p>如果要想在当前页页能触发 storage 事件,可以派发一个模拟事件:</p>
<pre><code class="language-js">(() =&gt; {
// 移除所有本地存储
localStorage.clear();

// 监听 storage 事件
window.addEventListener('storage', e =&gt; {
    console.log(e);
})

// 自定义写入函数,封装事件派发
function setItem (key, value) {
    // 模拟 storage 事件
    const ev = new StorageEvent('storage', {
      key,
      newValue: value,
      oldValue: localStorage.getItem(key),
      url: location.href,
    });
    window.dispatchEvent(ev);
    localStorage.setItem(key, value);
}
setItem('type', '公众号');
setItem('name', '前端路引');
})()
</code></pre>
<p>执行结果:</p>
<p><img src="https://img2024.cnblogs.com/blog/596097/202508/596097-20250811103534173-1382282956.png"></p>
<h3 id="功能检测">功能检测</h3>
<p>此处分享一个 MDN 文档中的检测 <code>localStorage</code> 是否可用的代码片段:</p>
<p><img src="https://img2024.cnblogs.com/blog/596097/202508/596097-20250811103539633-1354734963.png"></p>
<p>来源:https://developer.mozilla.org/zh-CN/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API</p>
<h2 id="大小与个数限制">大小与个数限制</h2>
<p>分享完 API 的使用方式,再看看各个浏览器之间的大小限制。</p>
<h3 id="chrome">Chrome</h3>
<p>Chrome 浏览器本地存储配额为 <code>5MB</code> 大小,意思就是所有存储的数据(键和值一起的长度)加起来不能超过 5MB。</p>
<pre><code class="language-js">(() =&gt; {
// 移除所有本地存储
localStorage.clear();
const key = 'name';
const max = 5 * 1024 * 1024;
// 测试极限值
const value = 'a'.repeat(max - key.length);
// 测试中文
// const value = '中'.repeat(max - key.length);
// 测试溢出
// const value = 'a'.repeat(max - key.length + 1);
localStorage.setItem(key, value);
})()
</code></pre>
<p>以上代码为刚好能存下的长度,如果超出一个字符,将会报错:</p>
<pre><code class="language-bash">Uncaught QuotaExceededError: Failed to execute 'setItem' on 'Storage': Setting the value of '****' exceeded the quota.
</code></pre>
<p>错误截图:</p>
<p><img src="https://img2024.cnblogs.com/blog/596097/202508/596097-20250811103547362-1073799076.png"></p>
<h3 id="edge">Edge</h3>
<p>自从 Edge 换成 Chromium 内核之后,它俩的所有行为基本表现一直,以前的 IE 内核没做测试,有兴趣的同学可以测试看看 IE 内核的表现行为。</p>
<h3 id="firefox">Firefox</h3>
<p>Firefox 也是限制 5MB 大小,但在溢出时的报错不一样:</p>
<pre><code class="language-bash">Uncaught DOMException: The quota has been exceeded.
</code></pre>
<p>错误截图:</p>
<p><img src="https://img2024.cnblogs.com/blog/596097/202508/596097-20250811103551647-114321341.png"></p>
<hr>
<p>根据以上测试结果得出:Firefox(138.0.4)、Edge(136.0.3240.92)、Chrome(136.0.7103.114)三大浏览器都是共用 5MB 存储空间,数量与每个本地储存项的大小有关,比如每次写入一个 <code>1MB</code> 的数据,那么就支持写入 5 个!!</p>
<p>中英文:<strong>与 Cookie 不同,localStorage 中的中文和英文计算方式一致,一个中文也按照一个字符计算!!</strong></p>
<h2 id="写在最后">写在最后</h2>
<p><code>localStorage</code> 仅支持字符串存储,所以在存储 JS 的 JSON 数据时,需要将 JSON 数据转为字符串再存储。</p>
<p>由于本人是 windows 环境,所以无法测试 Safari 浏览器的具体情况,有兴趣可以自测一下(有网友测试 safari 13.0.2 限制 2.5MB)。</p>
<p>在移动端的浏览器和 Webview 中使用 <code>localStorage</code> 时需注意,由于 APP 会自动优化存储空间,写在本地存储中的数据随时都可能被清空删除,所以本地存储的数据是不可靠的。</p>


</div>
<div id="MySignature" role="contentinfo">
    <p>&nbsp;</p>
<p style="font-size: 18px;font-weight: bold;">文章首发于微信公众号【<span style="color:rgb(255, 71, 87)">前端路引</span>】,欢迎 <span style="color:#4ec259">微信扫一扫</span> 查看更多文章。</p>
<p>
<img style="max-width: 320px;" src="https://images.cnblogs.com/cnblogs_com/linx/2447020/o_250228035031_%E5%85%AC%E4%BC%97%E5%8F%B7%E4%BA%8C%E7%BB%B4%E7%A0%81.png"/>
</p>
<p>本文来自博客园,作者:前端路引,转载请注明原文链接:https://www.cnblogs.com/linx/p/19031593</p>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/linx/p/19031593
頁: [1]
查看完整版本: Web前端入门第 83 问:JavaScript localStorage 有大小限制吗?溢出会怎样?