JavaScript LocalStorage 完整指南
对于大多数 web 浏览器,web 存储 API 提供了在浏览器中存储键值对的机制。它通常分为 localStorage
和 sessionStorage
,两者之间的主要区别是浏览器存储数据的时间。使用 sessionStorage
,「一旦会话结束或浏览器关闭,数据就会被删除」。但是,localStorage
中的数据会一直保存到清除为止。
localStorage
特性在许多用例中都是有帮助的。本文将详细介绍 localStorage
及其工作原理,以便你可以在应用程序中使用它。
1. 为什么需要 localStorage?
localStorage
中有许多有用的特性,包括「存储用户信息」的功能,以及允许你根据需要脱机工作的功能。
作为 web 浏览器中 web 存储 API 的一部分,localStorage
的工作原理类似于 cookie
。然而,它可以存储更多的数据。在谷歌 Chrome 中,每个域的存储空间最大为 5 MB
。
因为 internet 可能不是在任何地方都可以持续访问,localStorage
使你能够离线工作。你也可以存储网页的状态,即使 HTTP 是无状态的。假设你只想使用某个站点的黑暗主题。使用 localStorage
,你不必每次重新打开浏览器并访问站点时都更改主题。
2. localStorage 的好处
使用 localStorage
有很多好处,包括以下几点:
- 「更多的存储空间」:如前所述,
localStorage
在大多数浏览器中可以存储高达5MB
的数据,远远超过cookie
所能容纳的。 - 「对开发人员友好的 API」:该 API 可以方便地「访问」和「添加」
localStorage
中的数据。在任何浏览器上,都可以从Window
对象访问localStorage
函数。你可以通过写window.localStorage.setItem("Test data ", "Hello from localStorage")
来添加数据。 - 「持久性」:使用
localStorage
最常见的原因之一是保持数据持久性。虽然sessionStorage
也可以以key-value
的形式存储数据,但当会话结束时,它将被清除。但是,使用localStorage
,数据是连续的,直到显式删除为止。
3. localStorage 使用案例
以下是 localStorage
的一些常见用例。
3.1 保存 Access Tokens
localStorage
的一个广泛用途是在用户端存储访问令牌(如 JWT
令牌),以便用户在指定的时间内保持登录状态。
然而这是不安全的,永远不应该这样做,因为它可以在相同的域上使用 JavaScript 访问。这意味着在页面上运行的任何 JavaScript 代码都可以访问存储,使你的应用程序容易受到「跨站点脚本(XSS)攻击」。
应用程序还经常使用第三方脚本来获得分析或广告,即使是单个脚本被破坏,你也有被黑客攻击的风险。
3.2 保存部分提交的表单数据
如果用户正在填写一个长表单,localStorage
可以帮助存储部分数据。即使在开始填写表单和提交表单之间的互联网断开,用户也不会丢失他们的输入,可以从停止的地方继续。
3.3 缓存
当你的页面在1秒内加载时,客户转化率可以提高 2.5 倍。建立一个缓慢的网站不再是一个选择。但是,当终端用户请求特定的数据,并且请求必须通过网络传输,并伴随着相关的延迟时,缓存就可以优化性能。localStorage
可用于缓存网站或存储静态数据,以便在页面离线时显示客户端信息,然后在 internet 重新连接时获取必要的数据。
3.4 标签间同步数据
使用 localStorage
,用户可以在浏览器选项卡上打开一个计时器网站,启动计时器,然后打开同一网站的另一个选项卡,在两个选项卡之间同步计时器。你还可以在标签之间同步音乐或视频播放器。
3.5 预先的数据
可以使用 localStorage
存储预填充的应用程序版本。当用户访问你的应用程序时,他们立即在屏幕上看到一些东西,然后你的应用程序可以调用后端获取新信息。
4. 对 localStorage 执行操作
在对 localStorage
执行操作时,可以选择一些方法。它们是:
setItem()
getItem()
removeItem()
clear()
key()
以下是关于每一个的更多细节。
4.1 使用 setItem 存储项
setItem
方法用于将值存储到 localStorage
。该方法接受两个参数:key
和 value
。key
用于以后获取数据。下面是一个使用 setItem
方法存储数据的简单示例:
window.localStorage.setItem("Data", "Hello from localStorage")
如果在浏览器控制台上运行这段代码,它将在 localStorage
上存储名为 Data
的键和值 Hello from localStorage
。
运行代码之后,如果打开浏览器开发工具的 Applications
选项卡并单击 localStorage
,就可以看到 Data
键。
「注意」:你只能在 localStorage
中存储字符串。(在 Firefox 和 Chrome 上,localStorage
数据存储在 Sqlite 数据库中。)如果希望保留数组或对象,一个简单的方法是使用 JSON.stringify
方法将数据转换为 JSON
字符串。
4.2 使用 getItem 访问特定项
localStorage API 使用 getItem
方法检索数据。该方法接受一个参数,该参数是数据的 key
。如果没有找到数据,该方法返回 null
。
代码的语法如下所示:
window.localStorage.getItem("Data"); // Hello from localStorage window.localStorage.getItem("data"); // null
4.3 使用 removeItem 删除特定项
顾名思义,removeItem()
方法从 localStorage
中删除一个特定的键值对。数据的语法类似于 getItem
。它还接受单个参数,即项的键,如果项不可用,则返回 undefined
。
window.localStorage.removeItem("Data");
你可以检查浏览器开发工具的 Applications
选项卡,以确认 key
已被删除。
4.4 使用 clear 删除所有项
如果要清除特定域的 localStorage
,请使用 clear
方法。它不接受任何参数,并删除域的所有 localStorage
项。
window.localStorage.clear();
4.5 使用 key 检索键
当你想循环遍历 localStorage
的键时,key
方法就很方便了。它的参数是一个数字。该编号可以是 localStorage
项的索引位置。
这里有一个例子:
window.localStorage.setItem('Test', 'test'); // Adds New Item window.localStorage.key(0); // Test
如果域的 localStorage
已经拥有一些值,则返回值可能不同。
5. 监听「存储事件」
要使用 DOM
监听与 localStorage
相关的事件,可以使用 storage
事件。把它放在 window.addEventListener
可以帮助你在调用存储事件时执行 DOM
操作。下面是一个监听存储事件的简单示例:
window.addEventListener("storage", myFunction); function myFunction(event) { document.getElementById("app").innerHTML = "Change Made"; } function changeValue() { const newWindow = window.open("", "myWindow"); newWindow.localStorage.setItem("mytime", Date.now()); newWindow.close(); }
每当对 localStorage
进行更改时,代码将内部 HTML ID 为 app
的 h1
设置为 change made
。在本例中,一个新项被添加到新窗口的 localStorage
中,在将值写入 localStorage
之后,窗口将关闭。下面是上面代码的HTML:
<h1 id="app"></h1> <button onclick="changeValue()">Change a Storage Item</button>
6. sessionStorage 与 localStorage
localStorage
和 sessionStorage
确实有一些相似之处。例如:
- 两种存储类型都由 web 存储 API 提供
- 两者都只能存储字符串类型的
key-value
- 大多数情况下,数据限制在
5MB
左右 - 两种存储方式都只能存储键值对
然而,两者之间有一些区别。一个是「持久性」:存储在 localStorage
中的数据在会话中持续存在。打开新选项卡、访问新域或关闭浏览器都不会清除 localStorage
。另一方面,每当会话结束时,sessionStorage
将被清除。打开一个新选项卡或访问一个新域将清除特定域的会话。
另一个区别是,在少数浏览器的情况下,localStorage
不能在隐身模式下工作,但 sessionStorage
可以。在这些情况下,为 localStorage
代码编写包装器是一个好主意,以便使用 sessionStorage
。
7. localStorage 与 IndexedDB
IndexedDB 是一个用于在客户端存储大量结构化数据(包括文件)的 API。使用 IndexedDB
存储的数据也是持久化的,直到显式清除它为止。IndexedDB
还提供了用于模式版本控制的内置机制。
IndexedDB
提供了一些优于 localStorage
的优点。例如,与 localStorage
不同,IndexedDB
在与 worker
一起使用时不会阻塞 DOM。然而,localStorage
略快于 IndexedDB
。localStorage
的 API 也更容易上手,使之成为更受欢迎的选择。
引入 IndexedDB
的主要原因是为了提供更好的 localStorage
版本。那么,为什么不在所有情况下都使用 IndexedDB
呢?如果希望在客户端存储结构化数据,IndexedDB
是更好的选择,特别是因为 localStorage
不是为存储敏感信息而构建的。但是如果你存储的是简单的、少量的键值对数据,请使用 localStorage
。
8. 小结
localStorage
特性可以为你的应用程序提供好处,包括可以将数据持久保存到你需要的时间的开放式存储,以及使应用程序脱机工作的能力。这种形式的数据存储并不是每个用例的最佳选择,在某些情况下可能需要考虑 IndexedDB
。