JS前端开发3种常见的Web存储机制——localStorage
、sessionStorage
、cookie
Hyplus目录
1 localStorage(本地存储)
localStorage是HTML5引入的一种本地存储机制,使开发者能够在用户浏览器中持久存储数据。这些数据不会随着页面刷新而丢失,并且除非用户主动清除或删除它们,否则会一直保留在用户的设备上。
特点:
- 数据没有过期时间。
- 数据存储量通常较大(一般为5MB左右,具体大小取决于浏览器)。
- 只能存储字符串类型的数据(复杂对象需先序列化)。
- 同源策略限制:只有来自相同协议、域名和端口的页面可以访问同一
localStorage
数据。
1.1 基本操作
localStorage
提供了一组简单方法来管理存储的数据(Key: Value)
:
- 存储数据:使用
setItem()
方法将数据存储至localStorage
,注意所有数据都会被转换成字符串格式存储
localStorage.setItem('name', 'Akira Syma');
- 获取数据:使用
getItem()
方法从localStorage
中检索数据
console.log(localStorage.getItem('name')); // 输出:Akira Syma
- 删除数据:使用
removeItem()
方法删除特定键对应的值
localStorage.removeItem('name');
- 清空所有数据:使用
clear()
方法清空整个localStorage
localStorage.clear();
- 遍历所有键值对:使用
key()
方法结合循环可以遍历所有键值对
for (let i = 0; i < localStorage.length; i++) {
let key = localStorage.key(i);
console.log(`${key}: ${localStorage.getItem(key)}`);
}
1.2 序列化存储
由于localStorage
只能存储字符串类型的数据,因此当需要存储复杂数据结构(如对象或数组)时,必须先将其序列化为JSON格式,再进行存储。
- 存储对象:
const user = { name: 'Akira Syma', age: 108 };
localStorage.setItem('user', JSON.stringify(user)); // 序列化
- 读取对象
const storedUser = JSON.parse(localStorage.getItem('user')); // 反序列化
console.log(storedUser.name); // 输出: Akira Syma
1.3 应用示例
localStorage
非常适合用于存储不需要频繁更新且对安全性要求不高的数据,以下是一些典型的应用场景:
- 用户偏好设置:如主题选择、语言偏好等
function saveTheme(theme) {
localStorage.setItem('theme', theme);
}
function loadTheme() {
return localStorage.getItem('theme') || 'light'; // 默认为浅色主题
}
- 表单自动保存:在用户填写长表单时,可以定期保存表单状态,防止因意外关闭页面导致的信息丢失
setInterval(() => {
const formState = document.querySelector('form').value;
localStorage.setItem('formState', formState);
}, 5000); // 每5秒保存一次
- 离线应用:对于支持离线使用的应用,可以预先缓存一些关键数据,以便在网络不可用时也能提供基本服务
1.4 注意事项
使用localStorage
时需注意以下几点:
- 同源策略:
localStorage
数据仅在同一协议、域名和端口下可见,这有助于保护用户隐私,但也意味着不同网站之间无法共享数据。 - 容量限制:这是各Web存储策略共同存在的问题,尽管大多数现代浏览器提供了较大的存储空间(约5MB),但当接近上限时,可能会触发警告或错误。合理规划存储内容非常重要。
- 性能考虑:过度依赖
localStorage
可能会影响页面加载速度,尤其是在处理大量数据时。建议只存储必要的信息,并尽量减少读写频率。 - 跨窗口同步问题:打开不同的URL标签,其
localStorage
是不同的。当多个标签页同时打开并尝试修改相同的localStorage
数据时(多个标签页打开的是完全相同的URL),可能会出现数据不一致的情况。由此可通过监听storage
事件来实现简单的跨窗口通信,如下所示——
window.addEventListener('storage', (event) => {
if (event.key === 'sharedData') {
console.log(`Shared data updated to: ${event.newValue}`);
}
});
2 sessionStorage(会话存储)
sessionStorage是HTML5引入的一种本地存储机制,使开发者能够在用户浏览器中为当前会话(Session)存储数据。这些数据会在页面关闭时自动清除,并且不会随着页面刷新而丢失。
特点:
- 数据仅在当前页面会话期间有效,关闭浏览器标签或窗口后数据会被清除。
- 同一域名下的不同页面可共享
sessionStorage
中的数据(若是通过同一个浏览器标签打开的)。 - 只能存储字符串类型的数据(复杂对象需先序列化)。
- 同源策略限制:只有来自相同协议、域名和端口的页面可以访问同一
sessionStorage
数据。
2.1 基本操作
与localStorage
非常相似,sessionStorage
提供了一组简单方法来管理存储的数据:
- 存储数据:使用
setItem()
方法将数据存储至sessionStorage
,注意所有数据都会被转换成字符串格式存储
sessionStorage.setItem('name', 'Akira Syma');
- 获取数据:使用
getItem()
方法从sessionStorage
中检索数据
console.log(sessionStorage.getItem('name')); // 输出:Akira Syma
- 删除数据:使用
removeItem()
方法删除特定键对应的值
sessionStorage.removeItem('name');
- 清空所有数据:使用
clear()
方法清空整个sessionStorage
sessionStorage.clear();
- 遍历所有键值对:使用
key()
方法结合循环可以遍历所有的键值对
for (let i = 0; i < sessionStorage.length; i++) {
let key = sessionStorage.key(i);
console.log(`${key}: ${sessionStorage.getItem(key)}`);
}
2.2 序列化存储
与localStorage
相同,由于sessionStorage
只能存储字符串类型的数据,因此当需要存储复杂数据结构(如对象或数组)时,必须先将其序列化为JSON格式,再进行存储。
- 存储对象:
const user = { name: 'Akira Syma', age: 108 };
sessionStorage.setItem('user', JSON.stringify(user)); // 序列化
- 读取对象
const storedUser = JSON.parse(sessionStorage.getItem('user')); // 反序列化
console.log(storedUser.name); // 输出: Akira Syma
2.3 应用示例
sessionStorage
非常适合用于存储只需要在当前会话期间保持的数据,以下是一些典型的应用场景:
- 表单自动保存:在用户填写长表单时,可以定期保存表单状态,防止因意外关闭页面导致的信息丢失(亦适合用
localStorage
实现)
setInterval(() => {
const formState = document.querySelector('form').value;
sessionStorage.setItem('formState', formState);
}, 5000); // 每5秒保存一次
window.addEventListener('beforeunload', () => {
if (sessionStorage.getItem('formState')) {
alert('您的表单数据已自动保存。');
}
});
- 购物车信息:对于电子商务网站,可以在
sessionStorage
中暂时存储用户的购物车内容,直至其完成购买或主动清空购物车
function addToCart(item) {
let cart = JSON.parse(sessionStorage.getItem('cart')) || [];
cart.push(item);
sessionStorage.setItem('cart', JSON.stringify(cart));
}
function viewCart() {
return JSON.parse(sessionStorage.getItem('cart')) || [];
}
- 会话级别的用户偏好设置:如临时的主题选择或语言切换等
function saveTheme(theme) {
sessionStorage.setItem('theme', theme);
}
function loadTheme() {
return sessionStorage.getItem('theme') || 'light'; // 默认为浅色主题
}
2.4 注意事项
使用sessionStorage
时需注意以下几点:
- 会话依赖性:
sessionStorage
数据仅在当前页面会话期间有效,关闭浏览器标签或窗口后数据会被清除。这意味着其不适合长期存储重要数据。 - 同源策略:
sessionStorage
数据仅在同一协议、域名和端口下可见,这有助于保护用户隐私,但也意味着不同网站之间无法共享数据。 - 容量限制:这是各Web存储策略共同存在的问题,尽管大多数现代浏览器提供了较大的存储空间(约5MB),但当接近上限时,可能会触发警告或错误。合理规划存储内容非常重要。
- 跨窗口同步问题:
sessionStorage
是基于各浏览器标签页或窗口独立的存储机制,这意味着不同标签页或窗口之间的sessionStorage
是完全隔离的,一个标签页无法直接访问另一个标签页的sessionStorage
数据。即使多个标签页打开的是完全相同的URL,每个标签页的sessionStorage
仍然是独立的。- 需要注意的是,由于
sessionStorage
的这种独立性,其不支持跨页面通信,亦无法通过监听storage
事件来实现跨窗口同步。若需要在多个标签页间共享或同步数据,应考虑使用localStorage
或者其他解决方案,例如IndexedDB或通过服务器端进行数据同步。
- 需要注意的是,由于
3 Cookie
Cookie是一种存储于客户端(通常是用户的浏览器)的数据片段,允许网站在用户访问期间或之后记住某些信息。这些信息可以是简单的偏好设置,亦可以是复杂的会话标识符。
特点:
- 每次请求都会自动发送给服务器:这意味着Cookie中的数据会在每个HTTP请求中被发送回服务器,增加了网络流量。
- 大小限制约为4KB:单个域名下的所有Cookie的总大小通常不超过4KB。
- 支持设置过期时间:可以设置Cookie的有效期,过期后会被自动删除。
- 安全性选项:可设置
Secure
和HttpOnly
标志增强安全性。 - 同源策略:Cookie数据仅在同一协议、域名和端口下可见。
3.1 基本操作
Cookie是一串特殊的字符串,可通过document.cookie
来读取、写入和删除Cookie:
- 设置Cookie:直接给
document.cookie
赋值来设置一个新Cookie,需要指定名称、值以及可选的属性如过期时间、路径等- 注:
expires
参数指定了Cookie的过期日期,若不设置,则Cookie将被视为会话Cookie,在关闭浏览器时自动删除;path
参数指定了Cookie可用的路径,默认为/
- 注:
// 设置一个名为username的Cookie,值为Akira Syma,并设置过期时间为一年
document.cookie = "username=Akira Syma; expires=" + new Date(2026, 3, 2).toUTCString() + "; path=/";
- 获取Cookie:直接使用
document.cookie
可获取所有Cookie,返回的是一个包含所有Cookie的字符串,各Cookie之间用分号加空格隔开。通常还需编写辅助函数来解析特定的Cookie
// 获取全部Cookie
console.log(document.cookie); // 输出:"username=Akira Syma"
// 获取指定Cookie
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
console.log(getCookie('username')); // 输出:Akira Syma
- 删除Cookie:通过将Cookie的过期时间设置为过去的时间来删除Cookie
document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
3.2 安全性和隐私保护
为了提高安全性,Cookie提供了几个重要的标志:
Secure
:若设置了该标志,则Cookie只能通过HTTPS协议传输,不能通过HTTP传输,这有助于防止中间人攻击
document.cookie = "username=Akira Syma; Secure; path=/";
HttpOnly
:若设置了该标志,则JS代码无法访问该Cookie,只能通过HTTP(S)请求发送到服务器,这有助于防御XSS攻击
document.cookie = "sessionToken=abc123xyz; HttpOnly; path=/";
SameSite
:控制是否可以在跨站请求中携带Cookie,可取3种值——Strict
、Lax
、None
,其中None
必须与Secure
标志一起使用
document.cookie = "sessionToken=abc123xyz; SameSite=Strict; path=/";
3.3 应用示例
Cookie曾在许多场景中都有广泛应用,以下是几个典型的应用示例:
- 会话管理:存储会话标识符(Session ID),以便服务器能够识别用户并在多个页面请求之间保持登录状态
// 设置Session ID
document.cookie = "sessionId=abc123xyz; path=/";
// 获取Session ID
const sessionId = getCookie('sessionId');
- 用户偏好设置:Cookie亦能用于记住用户的语言选择、主题颜色等偏好设置
// 设置用户语言偏好
document.cookie = "preferredLanguage=en; expires=" + new Date(2026, 3, 2).toUTCString() + "; path=/";
// 获取用户语言偏好
const language = getCookie('preferredLanguage') || 'en';
- 购物车信息:Cookie亦能用于暂时存储用户的购物车内容,直至其完成购买或主动清空购物车
// 添加商品到购物车
function addToCart(item) {
let cart = JSON.parse(getCookie('cart')) || [];
cart.push(item);
document.cookie = `cart=${JSON.stringify(cart)}; path=/`;
}
// 查看购物车
function viewCart() {
return JSON.parse(getCookie('cart')) || [];
}
3.4 注意事项
使用Cookie
时需注意以下几点:
- 隐私问题:用户可能会对网站存储过多的个人信息感到不安,因此应尽量减少不必要的Cookie使用,并确保遵守相关的隐私政策和法规。
- 性能影响:每次HTTP请求都会发送所有的Cookie,因此应尽量减小Cookie的大小,并避免不必要的Cookie发送。
- 安全性考虑:对于敏感信息,建议使用
Secure
和HttpOnly
标志,并结合SameSite
属性来防止CSRF和XSS攻击。
4 总结
特性 | localStorage |
sessionStorage |
Cookie |
---|---|---|---|
存储大小 | 约5MB | 约5MB | 约4KB |
有效期 | 永久 | 页面会话期间 | 可设置 |
作用域 | 同源 | 同源 | 同源 |
传输到服务器 | 不传输 | 不传输 | 自动传输 |
使用场景 | 用户偏好设置 | 表单数据暂存 | 登录状态跟踪 |