13 本地存储
loyalvi Lv7

10 本地存储

几种储存方法

浏览器本地存储提供了几种不同的方式来在客户端存储数据,每种方式都有其特定的用途和特点。以下是几种常见的浏览器本地存储方法:

  • 存储量:每个域名下最多可存储 20 个 Cookie,每个 Cookie 最大 4KB。
  • 特点
    • 自动发送:Cookie 会随着 HTTP 请求自动发送到服务器,无需前端手动操作。
    • 跨会话存储:可以设置过期时间,即使关闭浏览器后数据依然存在。
    • 安全性:可以通过设置 HttpOnlySecure 标志来提高安全性,防止跨站脚本攻击(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
    21
    function 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
    6
    function setDataWithTimer(key, value, ttl) {
    sessionStorage.setItem(key, value);
    setTimeout(() => {
    sessionStorage.removeItem(key);
    }, ttl);
    }

封装 localStorage 实现过期时间

  • 原理:封装 localStoragesetItemgetItem 方法,在存储数据时记录过期时间,并在读取数据时检查是否过期。
  • 示例代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    const 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的SameSite属性所导致的。以下是一些常见的解决方案:

1. 使用CORS(跨域资源共享)

CORS是解决跨域问题的最常见和有效的方法之一。通过在服务器端设置特定的HTTP响应头,可以允许浏览器发送和接收跨域请求并携带Cookie。

服务器端配置

  • 设置Access-Control-Allow-Origin:指定允许跨域访问的源。可以是具体的域名,不推荐使用*,因为这会允许任何域访问。
  • 设置Access-Control-Allow-Credentials:设置为true,表示允许发送Cookie。
  • 设置Access-Control-Allow-Methods:指定允许的HTTP方法,如GETPOST等。
  • 设置Access-Control-Allow-Headers:指定允许的HTTP头。
    例如,在Node.js中可以这样配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const express = require('express');
const cors = require('cors');
const app = express();
const corsOptions = {
origin: 'http://example.com',
methods: 'GET,POST',
allowedHeaders: 'Content-Type',
credentials: true // 允许携带Cookie
};
app.use(cors(corsOptions));
app.get('/data', (req, res) => {
res.json({ message: 'This is CORS-enabled for all origins!' });
});
app.listen(3000, () => {
console.log('CORS-enabled web server listening on port 3000');
});

客户端配置

在客户端发起请求时,需要设置credentials属性为include,以便浏览器发送Cookie。例如,使用fetch API时可以这样配置:

1
2
3
4
5
6
7
fetch('http://example.com/data', {
method: 'GET',
credentials: 'include'
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

2. 设置Cookie的SameSite属性

Cookie的SameSite属性可以控制Cookie在跨域请求中的行为。有三种值可以设置:StrictLaxNone

  • Strict:最为严格,完全禁止第三方Cookie,跨站点时,任何情况下都不会发送Cookie。
  • Lax:规则稍稍放宽,大多数情况也是不发送第三方Cookie,但是导航到目标网址的GET请求除外。
  • None:Cookie只能通过HTTPS协议发送,并且必须同时设置Secure属性。
    例如,在Node.js中可以这样设置Cookie:
1
2
3
4
res.cookie('name', 'value', {
sameSite: 'None',
secure: true
});

3. 使用JSONP

JSONP(JSON with Padding)是一种解决跨域问题的传统方法。它利用了<script>标签不受同源策略限制的特点,通过动态创建<script>标签来请求跨域资源,并在资源返回时执行一个回调函数。
例如,客户端代码可以这样写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JSONP Example</title>
</head>
<body>
<script>
function handleResponse(data) {
console.log('Received data:', data);
}
var script = document.createElement('script');
script.src = 'http://yourserver.com/data?callback=handleResponse';
document.head.appendChild(script);
</script>
</body>
</html>

服务器端代码可以这样写:

1
2
3
4
5
app.get('/data', (req, res) => {
const callback = req.query.callback;
const data = { message: 'This is cross-origin data with JSONP!' };
res.send(`${callback}(${JSON.stringify(data)})`);
});

4. 使用代理服务器

通过设置代理服务器,可以将请求转发到目标服务器,从而绕过浏览器的同源策略。例如,使用Nginx配置反向代理:
nginx复制

1
2
3
4
5
6
7
8
9
10
11
server {
listen 80;
server_name yourdomain.com;
location /api {
proxy_pass http://targetdomain.com;
proxy_set_header Host targetdomain.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

5. 设置document.domain

如果一级域名相同,只是二级域名不同,可以通过设置document.domain共享Cookie。例如:

1
2
3
4
5
6
7
8
9
10
11
12
http://javascript.exam.cn/text.html:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script>
document.domain = 'exam.cn';
document.cookie = "name=value";
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
http://category.exam.cn/text.html:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script>
document.domain = 'exam.cn';
alert(document.cookie); // 输出:name=value
</script>
</body>
</html>

总结

解决Cookie跨域问题的方法有多种,具体选择哪种方法取决于具体的应用场景和需求。CORS是最常用和最灵活的方法,但需要服务器端和客户端的配合。设置Cookie的SameSite属性和使用代理服务器也是常见的解决方案。在选择方法时,需要综合考虑安全性、灵活性和开发成本。

由 Hexo 驱动 & 主题 Keep
访客数 访问量