10 本地存储
几种储存方法
浏览器本地存储提供了几种不同的方式来在客户端存储数据,每种方式都有其特定的用途和特点。以下是几种常见的浏览器本地存储方法:
1. Cookie
- 存储量:每个域名下最多可存储 20 个 Cookie,每个 Cookie 最大 4KB。
- 特点:
- 自动发送:Cookie 会随着 HTTP 请求自动发送到服务器,无需前端手动操作。
- 跨会话存储:可以设置过期时间,即使关闭浏览器后数据依然存在。
- 安全性:可以通过设置
HttpOnly和Secure标志来提高安全性,防止跨站脚本攻击(XSS)和非安全传输。
- 使用场景:适用于存储用户会话信息、用户偏好设置等需要与服务器交互的数据。
2. localStorage
- 存储量:通常为每个域名 5MB。
- 特点:
- 持久存储:数据存储在本地,即使关闭浏览器后数据依然存在,直到被明确删除。
- 同步操作:读写操作是同步的,可能会阻塞主线程。
- 仅限同源:只能在同源的页面之间共享数据。
- 使用场景:适用于存储不需要频繁与服务器交互的数据,如用户设置、缓存数据等。
3. sessionStorage
- 存储量:通常为每个域名 5MB。
- 特点:
- 会话存储:数据仅在当前浏览器会话中有效,关闭浏览器标签页后数据会被清除。
- 同步操作:读写操作是同步的,可能会阻塞主线程。
- 仅限同源:只能在同源的页面之间共享数据。
- 使用场景:适用于存储临时数据,如表单数据、页面状态等,这些数据不需要在浏览器会话之间持久存在。
4. IndexedDB
- 存储量:通常为每个域名 50MB 或更多,具体取决于浏览器和用户设置。
- 特点:
- 非关系型数据库:提供类似于数据库的存储方式,可以存储结构化数据。
- 异步操作:读写操作是异步的,不会阻塞主线程。
- 事务支持:支持事务,可以保证数据的一致性和完整性。
- 使用场景:适用于存储大量结构化数据,如离线应用、大型应用的数据缓存等。
5. Web SQL Database(已废弃)
- 存储量:通常为每个域名 5MB 或更多。
- 特点:
- 关系型数据库:提供 SQL 语法来操作数据。
- 异步操作:读写操作是异步的,不会阻塞主线程。
- 使用场景:由于已废弃,不推荐在新项目中使用。
选择合适的方法
- 数据量大小:根据需要存储的数据量选择合适的方法,如小量数据可使用 Cookie 或 sessionStorage,大量数据可使用 IndexedDB。
- 数据持久性:根据数据是否需要跨会话持久存在选择 localStorage 或 sessionStorage。
- 数据结构:根据数据的结构选择 IndexedDB 进行结构化存储。
- 与服务器交互:如果需要与服务器频繁交互,可以使用 Cookie。
根据具体的应用需求和场景,选择合适的浏览器本地存储方法,可以有效地提高应用的性能和用户体验。
设置失效时间来清除本地存储的数据
在前端开发中,可以通过设置失效时间来清除本地存储的数据。以下是几种常用的方法:
使用 localStorage 和时间戳
- 原理:在存储数据时,同时存储一个时间戳,表示数据的过期时间。当读取数据时,检查当前时间与存储的时间戳,如果超过了设定的失效时间,则清除数据。
- 示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21function setDataWithExpiry(key, value, ttl) {
const now = new Date();
const item = {
value: value,
expiry: now.getTime() + ttl,
};
localStorage.setItem(key, JSON.stringify(item));
}
function getData(key) {
const itemStr = localStorage.getItem(key);
if (!itemStr) {
return null;
}
const item = JSON.parse(itemStr);
const now = new Date();
if (now.getTime() > item.expiry) {
localStorage.removeItem(key);
return null;
}
return item.value;
}
使用 sessionStorage 和定时器
- 原理:
sessionStorage存储的数据在浏览器会话结束时会自动清除。可以结合定时器来提前清除数据。 - 示例代码:
1
2
3
4
5
6function setDataWithTimer(key, value, ttl) {
sessionStorage.setItem(key, value);
setTimeout(() => {
sessionStorage.removeItem(key);
}, ttl);
}
封装 localStorage 实现过期时间
- 原理:封装
localStorage的setItem和getItem方法,在存储数据时记录过期时间,并在读取数据时检查是否过期。 - 示例代码:通过这些方法,可以有效地管理本地存储的数据,确保数据在指定的时间后自动清除,从而提升应用的安全性和性能。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23const customStorage = {
setItem(key, value, ttl) {
const now = new Date().getTime();
const item = {
value: value,
expiry: now + ttl,
};
localStorage.setItem(key, JSON.stringify(item));
},
getItem(key) {
const itemStr = localStorage.getItem(key);
if (!itemStr) {
return null;
}
const item = JSON.parse(itemStr);
const now = new Date().getTime();
if (now > item.expiry) {
localStorage.removeItem(key);
return null;
}
return item.value;
},
};
cookie 跨域问题
Cookie跨域问题是指在不同域之间进行请求时,Cookie无法被正确传递的问题。这主要是由于浏览器的同源策略和Cookie的SameSite属性所导致的。以下是一些常见的解决方案:
1. 使用CORS(跨域资源共享)
CORS是解决跨域问题的最常见和有效的方法之一。通过在服务器端设置特定的HTTP响应头,可以允许浏览器发送和接收跨域请求并携带Cookie。
服务器端配置
- 设置
Access-Control-Allow-Origin:指定允许跨域访问的源。可以是具体的域名,不推荐使用*,因为这会允许任何域访问。 - 设置
Access-Control-Allow-Credentials:设置为true,表示允许发送Cookie。 - 设置
Access-Control-Allow-Methods:指定允许的HTTP方法,如GET、POST等。 - 设置
Access-Control-Allow-Headers:指定允许的HTTP头。
例如,在Node.js中可以这样配置:
1 | const express = require('express'); |
客户端配置
在客户端发起请求时,需要设置credentials属性为include,以便浏览器发送Cookie。例如,使用fetch API时可以这样配置:
1 | fetch('http://example.com/data', { |
2. 设置Cookie的SameSite属性
Cookie的SameSite属性可以控制Cookie在跨域请求中的行为。有三种值可以设置:Strict、Lax和None。
- Strict:最为严格,完全禁止第三方Cookie,跨站点时,任何情况下都不会发送Cookie。
- Lax:规则稍稍放宽,大多数情况也是不发送第三方Cookie,但是导航到目标网址的GET请求除外。
- None:Cookie只能通过HTTPS协议发送,并且必须同时设置
Secure属性。
例如,在Node.js中可以这样设置Cookie:
1 | res.cookie('name', 'value', { |
3. 使用JSONP
JSONP(JSON with Padding)是一种解决跨域问题的传统方法。它利用了<script>标签不受同源策略限制的特点,通过动态创建<script>标签来请求跨域资源,并在资源返回时执行一个回调函数。
例如,客户端代码可以这样写:
1 |
|
服务器端代码可以这样写:
1 | app.get('/data', (req, res) => { |
4. 使用代理服务器
通过设置代理服务器,可以将请求转发到目标服务器,从而绕过浏览器的同源策略。例如,使用Nginx配置反向代理:
nginx复制
1 | server { |
5. 设置document.domain
如果一级域名相同,只是二级域名不同,可以通过设置document.domain共享Cookie。例如:
1 | http://javascript.exam.cn/text.html: |
1 | http://category.exam.cn/text.html: |
总结
解决Cookie跨域问题的方法有多种,具体选择哪种方法取决于具体的应用场景和需求。CORS是最常用和最灵活的方法,但需要服务器端和客户端的配合。设置Cookie的SameSite属性和使用代理服务器也是常见的解决方案。在选择方法时,需要综合考虑安全性、灵活性和开发成本。