引言
想象这样的场景:当你在电商网站精心挑选了几件商品加入购物车,突然接到一个紧急电话需要立即处理。匆忙关闭浏览器时,你是否担心过这些挑选好的商品会全部消失? 令人欣慰的是,几小时后当你再次打开网站,发现购物车里的商品依然安静地等待着你的归来。这种"记忆犹新"的体验背后,正是现代Web存储技术的魔法在发挥作用。
然而,这种看似简单的功能实现却面临着技术上的根本性挑战。由于HTTP协议本质上是无状态的,就像金鱼只有7秒记忆一般,服务器默认会"忘记"每个请求之间的关联信息。这意味着当用户添加商品到购物车后刷新页面,服务器很可能已经"不记得"这个操作——购物车会恢复成空白状态。
为了跨越这个技术鸿沟,开发者们创造了多种Web存储解决方案。这些技术不仅能记住用户的购物车内容,还能保存个性化设置、表单填写进度等各类状态信息。更重要的是,它们能确保即使用户关闭浏览器后再访问,这些数据依然能够完美重现,为用户打造连续、一致的浏览体验。在这篇文章中,我们将深入解析这些Web存储技术。
Cookie
Cookie,饼干嘛,它很小,其本质上是一小段文本信息(通常不超过4KB),由服务器发送到用户浏览器并保存在本地,浏览器每次向服务器发起请求时都会自动携带 Cookie。主要用于在无状态的 HTTP 协议下维持用户状态。
Cookie可设置过期时间(会话 Cookie 或持久 Cookie)
Cookie的最核心用途就是用来做用户身份认证
- 服务器在用户登录后下发包含
session ID的 Cookie,后续请求自动携带该 ID 来识别用户。 - 或者用来记录个性化的存储,比如你用的什么主题,语言,地区所在啊等等
- 还可以用来临时记录你的购物车的状态
接下来我们来利用html+js写一段逻辑,只有浏览器携带cookie,才能实现登录状态:
首先我们先来写服务器端:
// node 后端
// node 内置的核心模块
// js在命令行运行
// js有两种模块化方案
// require node 早期的模块化commonJS
// import es6 更先进的模块化方案
// old 老版本写法
// node 受欢迎 中小项目开发
// 端口 对应的是某个服务
// 3306 mysql 80 web 服务 进程(资源) 线程(执行)
// 1234 8080 占用端口
// domin (localhost) -> ip地址 (127.0.0.1)->对应某台设备->port 设备上的某个服务(进程)
// 一台设备上可以有很多端口使用,有多个http服务
// 不要使用一些特殊端口
const http = require('http');
const fs = require('fs'); // file system
const path = require('path'); // 路径模块
const server = http.createServer((req, res) => {
if (req.method == 'GET' && (req.url == '/' || req.url == '/index.html')) {
console.log(__dirname,
path.join(__dirname, 'public', 'index.html')
);
fs.readFile(path.join(__dirname, 'public', 'index.html'),
// 回调函数 异步 callback
(err, content) => {
if (err) {
res.writeHead(500); // 5XX 代表服务器错误
res.end('Server error');
return;
}
// 请求头
res.writeHead(200, { 'Content-Type': 'text/html' })
res.end(content)
})
} // 如果访问的地址是'localhost:xxxx/'或者'localhost:xxxx/index.html,就返回这个文件'
-----------------------------------------------------------------------------------------------
if (req.method == 'POST' && req.url == '/login') {
// 用户名和密码的校验
// 写入响应头
res.writeHead(200, {
// 服务器端设置
'Set-Cookie': 'username = admin',
'Content-Type': 'application/json'
})
res.end(
JSON.stringify({
success: true,
msg: '登陆成功'
})
);
}
if (req.method == 'GET' && req.url == '/check-login') {
if (req.headers.cookie) {
res.writeHead(200, {
'Content-Type': 'application/json'
})
res.end(JSON.stringify({
loggedIn: true,
username: 'admin'
}));
} else {
res.end(JSON.stringify({
loggedIn: false,
username: ''
}));
}
}
})
server.listen(8080);
我们这里浅浅地写了一个服务器,横线的上方都是准备工作,下方才是实现登录的逻辑:
如果我们访问了/login路径,服务器就会给客户端发送一个cookie:'username = admin',当然通过登录后是需要校验的,这就是下面/check-login的作用,如果有cookie,就返回一个状态{ loggedIn: true, username: 'admin' },没有就返回相反的状态。
之后我们在前端进行校验:
document.addEventListener('DOMContentLoaded', async () => {
// 验证是否登录?
try {
const response = await fetch('/check-login')
const data = await response.json();
// 利用显示不同元素,来展现是否登录的效果
if (data.loggedIn) {
document.getElementById('loginSection').style.display = 'none';
document.getElementById('welcomeSection').style.display = 'block';
document.getElementById('userDisplay').textContent = data.username;
} else {
document.getElementById('loginSection').style.display = 'block';
document.getElementById('welcomeSection').style.display = 'none';
}
} catch (err) {
console.log(err)
}
})
OK,这样cookie的介绍就完成了。
其他存储方式
localStorage
localStorage 是 HTML5 提供的 客户端存储 API,用于在浏览器中持久化存储键值对数据。
| 特性 | 说明 |
|---|---|
| 存储大小 | 5~10MB(不同浏览器上限不同) |
| 存储类型 | 仅支持 字符串键值对(需手动序列化对象) |
| 数据持久性 | 关闭浏览器后 不会清除,需手动删除或通过代码清除 |
| 作用域 | 同源策略(相同协议+域名+端口共享数据) |
| API 同步/异步 | 同步操作(可能阻塞主线程,大量数据时需谨慎) |
| 是否自动发送到服务器 | ❌ 不会像 Cookie 那样随 HTTP 请求自动发送 |
一般都储存一些不需要频繁更新的数据。
具有localStorage.setItem(key,value)和localStorage.getItem(key),两个API,第一个可以设置要存储的值,第二个可以通过key访问所存储的值。
Session
在 Web 开发中,Session(会话) 是一种服务器端技术,用于 跟踪用户的状态。由于 HTTP 协议是无状态的,Session 机制能让服务器在多个请求之间记住用户信息(如登录状态、购物车数据等)。
| 特性 | 说明 |
|---|---|
| 存储位置 | 服务器端(如内存、数据库、Redis) |
| 生命周期 | 用户会话期间有效(默认关闭浏览器后失效,也可设置过期时间) |
| 安全性 | 比 Cookie 更安全(敏感数据不直接存储在客户端) |
| 依赖关系 | 通常依赖 Cookie(存储 Session ID)或 URL 重写 |
| 适用场景 | 登录状态管理、敏感数据存储(如用户权限、临时凭证) |
为什么说通常依赖cookie呢?这是因为客户端首次访问时:
- 服务器为该用户创建唯一 Session ID(如
sess_abc123)。 - 服务器存储 Session 数据(如
{ user_id: 123, is_logged_in: true })。 - 通过
Set-Cookie将 Session ID 发给浏览器(默认 Cookie 名为PHPSESSID、JSESSIONID等)。
之后每次请求链接,服务器都会根据cookie所携带的Session ID来辨认身份,查找对应的数据。
为什么说Session在浏览器关闭后失效?
Session的数据都会存储在Session-Cookie中,而会话级别的Cookie在浏览器关闭的时候就会进行销毁,这时Session也就失效了。
在关闭标签页时,浏览器不会销毁Session Cookie,但某些设置,如Chrome的退出时清理Cookie,会使得退出标签页的时候一同清理Cookie。
总结
Cookie、localStorage和Session是Web开发中三大核心存储方案。Cookie(≤4KB)由服务器通过Set-Cookie设置,自动随请求发送,适用于身份验证(如Session ID)。localStorage(5-10MB)持久存储客户端数据(需手动序列化),用于偏好设置或离线缓存。Session依赖服务端存储(如Redis),通过Session ID(通常存于Cookie)关联用户状态,适合敏感数据(如登录态)。三者协同实现无状态HTTP下的用户体验连续性,需根据安全性、生命周期和存储需求选择。