前言
浏览器本身常见的存储技术有:Cookie、localStorage、sessionStorage、IndexedDB、Web SQL Database、Cache Storage 等。
简单介绍
- Cookie:用于维持请求状态的小型文本文件,由网站通过用户的浏览器创建并存储。
- localStorage:localStorage 是 Web Storage API 的一部分,它是一种在浏览器中存储持久化数据的机制。它允许网页在用户的浏览器中保存键值对数据,并且这些数据在浏览器关闭后仍然有效,没有过期时间。
- sessionStorage:sessionStorage 也是 Web Storage API 的一部分,它是一种在浏览器中存储临时会话数据的机制。与 localStorage 不同,sessionStorage 中存储的数据仅在浏览器会话期间有效,即在用户关闭浏览器选项卡或窗口后,这些数据将被清除。
- IndexedDB:IndexedDB 是浏览器上的索引数据库,它允许网页在用户的浏览器上进行复杂的查询和事务操作。
- Web SQL Database:Web SQL Database 是一个基于 SQL 的浏览器数据库,可以在客户端存储结构化数据。虽然它曾经是 HTML5 的一部分,但目前已经被弃用,不再被推荐使用。现代浏览器更倾向于支持 IndexedDB
- Cache Storage:Cache Storage 是 Service Worker 的一部分,允许开发者对网络请求和响应进行缓存。它可以用于在离线状态下提供快速的资源访问,以及优化网页的性能和加载速度。
本篇主要是讨论前面提到的第二和第三种浏览器存储技术: localStorage 和 sessionStorage
localStorage
localStorage 是 Web Storage API 的一部分,它是一种在浏览器中存储持久化数据的机制。它允许网页在用户的浏览器中保存键值对数据,并且这些数据在浏览器关闭后仍然有效,没有过期时间,非用户主动删除(包括代码层面的删除)和清空浏览器数据,否则 localStorage 中的数据是永久保存的。
localStorage 的限制
- 容量限制:localStorage 的容量通常在 5MB 左右。如果当前页面的 localStorage 太大了就会导致页面很卡;如果添加的 localStorage 超出最大容量就会报错并无法成功添加。
- 类型限制:localStorage 的键值对都只能是字符串类型的。
- 同源限制:不同源的 localStorage 是不能共享的,如果域名相同,协议和端口号不同还是无法共享。
localStorage 怎么用?
localStorage 可以通过两种方法进行增、删、改、查,分别是 LocalStorage API 对应的方法 getItem、setItem、removeItem、clear 和 类似于对象的操作,通过类似于对象的操作的形式操作存在弊端(LocalStorage API 自身就有一些属性和方法),最好不要通过类似于对象的操作来操作 localStorage。
window.localStorage
获取整个 localStorage 对象。
localStorage 的增删改查
/** 设置/修改 localStorage **/
// API
window.localStorage.setItem('name', 'zhangsan');
// 对象操作(不能设置length、key、setItem、getItem、removeItem、clear等键)
window.localStorage['age'] = 20;
/** 查看 localStorage **/
// API(不能查看length、key、setItem、getItem、removeItem、clear等键)
window.localStorage.getItem('name'); // zhangsan
// 对象操作
window.localStorage['age']; // 20
/** 删除 localStorage **/
// API
window.localStorage.removeItem('name');
// 对象操作(不能删除length、key、setItem、getItem、removeItem、clear等键)
delete window.localStorage['age'];
/** 清空 localStorage **/
// API
window.localStorage.clear();
// 对象操作(不能清除length、key、setItem、getItem、removeItem、clear等键)
for (const key in window.localStorage) {
if (Object.hasOwnProperty.call(window.localStorage, key)) {
delete window.localStorage[key];
}
}
/** 根据索引获取键名 **/
localStorage.key(index);
// 获取存储在 localStorage 中的键值对的数量(即存储项的个数)。
localStorage.length;
sessionStorage
sessionStorage 也是 Web Storage API 的一部分,它是一种在浏览器中存储临时会话数据的机制。与 localStorage 不同,sessionStorage 中存储的数据仅在浏览器会话期间有效,即在用户关闭浏览器选项卡或窗口后,这些数据将被清除。下面是 MDN 上对于 sessionStorage 的说明:
- 页面会话在浏览器打开期间一直保持,并且重新加载或恢复页面仍会保持原来的页面会话。
- 在新标签或窗口打开一个页面时会复制顶级浏览会话的上下文作为新会话的上下文,这点和 session cookie 的运行方式不同。
- 打开多个相同的 URL 的 Tabs 页面,会创建各自的
sessionStorage。- 关闭对应浏览器标签或窗口,会清除对应的
sessionStorage。
查看英文原文
- Whenever a document is loaded in a particular tab in the browser, a unique page session gets created and assigned to that particular tab. That page session is valid only for that particular tab.
- A page session lasts as long as the tab or the browser is open, and survives over page reloads and restores.
- Opening a page in a new tab or window creates a new session with the value of the top-level browsing context, which differs from how session cookies work.
- Opening multiple tabs/windows with the same URL creates sessionStorage for each tab/window.
- Duplicating a tab copies the tab's sessionStorage into the new tab.
- Closing a tab/window ends the session and clears objects in sessionStorage.
下面分别对上面四点(英文版页面是六点)展开说明:
- 页面会话在浏览器打开期间一直保持,并且重新加载或恢复页面仍会保持原来的页面会话。 这个比较好理解,意思就是当页面刷新、页面跳转到其他不同源页面再返回时 sessionStorage 都不会丢失(在同一个标签页内从 a.com 跳转到 b.com 再跳转到 a.com ,最开始 a.com 的 sessionStorage 不会丢失), 只有关闭当前标签页 sessionStorage 才会被删除。
- 在新标签或窗口打开一个页面时会复制顶级浏览会话的上下文作为新会话的上下文,这点和 session cookie 的运行方式不同。 这个理解起来可能没那么方便,下面我直接列举可以复制当前标签页 sessionStorage 到新的标签页的情况:
- 通过
window.open(url, "_blank")打开一个新的同源的标签页 - 点击
rel属性为opener(不同时含有 noreferrer) 且target属性值为_blank的 a 标签打开一个新的同源的标签页。(右键新标签页打开或者Ctrl+点击打开新标签页是不会复制的)
<!-- 当前页面url为: http://localhost:3000/a.com --> <!-- 新的标签页不会复制当前页面 sessionStorage --> <a href="http://localhost:3000/a.com" target="_blank">页面A</a> <!-- 新的标签页会复制当前页面 sessionStorage --> <a href="http://localhost:3000/a.com" target="_blank" rel="opener referrer">页面A</a> <!-- 新的标签页会复制当前页面 sessionStorage --> <a href="http://localhost:3000/a.com" target="_blank" rel="opener">页面A</a> <!-- 新的标签页不会复制当前页面 sessionStorage --> <a href="http://localhost:3000/a.com" target="_blank" rel="opener noreferrer">页面A</a> - 通过
- 打开多个相同的 URL 的 Tabs 页面,会创建各自的
sessionStorage。 按照字面意思来理解就可以了。 - 关闭对应浏览器标签或窗口,会清除对应的
sessionStorage。 这个也是按照字面意思来理解就可以了。
需要注意的是上面提到的 复制 相当于 深拷贝,新标签页对 sessionStorage 的任何操作都不会影响原来标签页的 sessionStorage。
sessionStorage 的限制
- 容量限制:sessionStorage 的容量通常在 5MB 左右。如果当前页面的 sessionStorage 太大了就会导致页面很卡;如果添加的 sessionStorage 超出最大容量就会报错并无法成功添加。
- 类型限制:sessionStorage 的键值对都只能是字符串类型的。
- 同源限制:不同源的 sessionStorage 是不能共享的。
- 同标签页限制:只有在同一个标签页才可以读取同一个 sessionStorage。
- 有效期限制:sessionStorage 的有效期是会话级的,关闭对应浏览器标签或窗口,会清除对应的 sessionStorage
sessionStorage 怎么用?
sessionStorage 可以通过两种方法进行增、删、改、查,分别是 SessionStorage API 对应的方法 getItem、setItem、removeItem、clear 和 类似于对象的操作,通过类似于对象的操作的形式操作存在弊端(SessionStorage API 自身就有一些属性和方法),最好不要通过类似于对象的操作来操作 sessionStorage。
window.sessionStorage
获取整个 sessionStorage 对象。
sessionStorage 的增删改查
/** 设置/修改 sessionStorage **/
// API
window.sessionStorage.setItem('name', 'zhangsan');
// 对象操作(不能设置length、key、setItem、getItem、removeItem、clear等键)
window.sessionStorage['age'] = 20;
/** 查看 sessionStorage **/
// API(不能查看length、key、setItem、getItem、removeItem、clear等键)
window.sessionStorage.getItem('name'); // zhangsan
// 对象操作
window.sessionStorage['age']; // 20
/** 删除 sessionStorage **/
// API
window.sessionStorage.removeItem('name');
// 对象操作(不能删除length、key、setItem、getItem、removeItem、clear等键)
delete window.sessionStorage['age'];
/** 清空 sessionStorage **/
// API
window.sessionStorage.clear();
// 对象操作(不能清除length、key、setItem、getItem、removeItem、clear等键)
for (const key in window.sessionStorage) {
if (Object.hasOwnProperty.call(window.sessionStorage, key)) {
delete window.sessionStorage[key];
}
}
/** 根据索引获取键名 **/
sessionStorage.key(index);
// 获取存储在 sessionStorage 中的键值对的数量(即存储项的个数)。
sessionStorage.length;
localStorage、sessionStorage、Cookie、IndexedDB的对比
下面是localStorage、sessionStorage、Cookie和IndexedDB的对比:
| 特点 | 存储容量 | 生命周期 | 跨会话 | 目的 |
|---|---|---|---|---|
| localStorage | 通常几兆字节 | 永久存储 | 是 | 长期保存用户数据,如偏好设置、登录状态等 |
| sessionStorage | 通常几兆字节 | 当前会话期间 | 否 | 临时保存会话期间数据,如表单传递 |
| Cookie | 通常几KB | 可设置过期时间 | 是 | 在客户端和服务器间传递少量信息,如用户认证信息、会话标识等 |
| IndexedDB | 通常较大 | 永久存储 | 否 | 存储大量结构化数据,如离线应用、缓存数据等 |
总结:
- 如果你需要在不同会话间共享数据,使用
localStorage或Cookie。 - 如果你需要在当前会话期间共享数据,使用
sessionStorage。 - 如果你需要在客户端存储较大的结构化数据,使用
IndexedDB。