Cookie
一、Cookie 基础介绍
定义:Cookie 是服务器发送到用户浏览器并保存在本地的小型文本数据(通常 ≤4KB),浏览器会在后续请求中自动携带。
核心特性:
- 域名绑定:只对创建它的域名有效
- 存储限制:每个域名约 50 个 Cookie,总大小 ≤4KB
- 自动携带:浏览器在每次 HTTP 请求中自动发送
- 键值存储:简单字符串数据(
name=value
格式)
核心用途:
- 会话管理(用户登录状态)
- 个性化设置(主题/语言偏好)
- 用户行为跟踪(分析工具)
- 购物车数据暂存
二、Cookie 操作指南
1. 设置 Cookie
// 基础设置(会话级Cookie)
document.cookie = 'username=john_doe';
// 完整参数设置
document.cookie = `theme=dark;
expires=${new Date(Date.now() + 86400000).toUTCString()};
path=/;
domain=.example.com;
secure;
samesite=lax`;
关键参数:
expires
/max-age
:有效期(UTC 字符串或秒数)path
:生效路径(默认为当前路径)domain
:生效域名(默认为当前域名)secure
:仅 HTTPS 传输samesite
:跨站策略(lax
/strict
/none
)
2. 读取 Cookie
function getCookie(name) {
return document.cookie
.split('; ')
.find((row) => row.startsWith(`${name}=`))
?.split('=')[1];
}
console.log(getCookie('theme')); // 输出 "dark"
3. 删除 Cookie
// 通过设置过期时间为过去时删除
document.cookie = `username=; expires=${new Date(0).toUTCString()}; path=/`;
// 更严谨的删除方法(确保匹配原始参数)
function deleteCookie(name, path = '/', domain = '') {
let cookie = `${name}=; expires=${new Date(0).toUTCString()}; path=${path}`;
if (domain) cookie += `; domain=${domain}`;
document.cookie = cookie;
}
三、Cookie 生命周期
类型 | 设置方式 | 生命周期 |
---|---|---|
会话 Cookie | 不设 expires/max-age |
浏览器关闭时失效 |
持久 Cookie | 设置 expires 或 max-age |
到达指定时间后失效 |
第三方 Cookie | 跨域资源设置 | 遵循设置的有效期 |
生命周期控制:
// 7天后过期的Cookie
const expires = new Date(Date.now() + 7 * 86400000).toUTCString();
document.cookie = `user_token=abc123; expires=${expires}; path=/`;
四、安全与限制
1. 安全风险
- CSRF 攻击:恶意网站利用自动携带特性
- XSS 窃取:脚本读取敏感 Cookie
- 中间人攻击:未加密传输时被截获
2. 防护措施
// 安全设置组合(最佳实践)
document.cookie = `sessionId=xyz;
secure; // 仅HTTPS传输
httponly; // 禁止JavaScript访问
samesite=strict; // 禁止跨站携带
path=/;
max-age=3600`;
3. 浏览器限制
- 默认阻止第三方 Cookie(Safari/Firefox)
- SameSite=None 必须配合 Secure
- 隐私模式不保存持久 Cookie
五、面试高频问题
Cookie vs LocalStorage vs SessionStorage?
| 特性 | Cookie | LocalStorage | SessionStorage | | -------- | -------------- | ------------ | -------------- | | 生命周期 | 可设置过期时间 | 永久 | 会话级 | | 自动携带 | 是 | 否 | 否 | | 存储大小 | ≤4KB | 5-10MB | 5-10MB | | 访问权限 | 服务端和客户端 | 仅客户端 | 仅客户端 |
如何防范 CSRF 攻击?
- 设置
SameSite=Strict/Lax
- 添加 CSRF Token 验证
- 关键操作使用 POST 请求
- 设置
HttpOnly 的作用?
防止 XSS 攻击窃取 Cookie,设置后 JavaScript 无法读取该 Cookie
Cookie 域名作用域规则?
domain=example.com
:匹配 example.com 和子域- 不设 domain:仅精确匹配当前域名
- 禁止设置顶级域名(.com)
Cookie 编码要求?
- 键值需 URL 编码:
document.cookie = `${encodeURIComponent('user name')}=${encodeURIComponent( 'John Doe' )}`;
- 键值需 URL 编码:
六、最佳实践
最小化原则
- 仅存储必要数据(如 session ID)
- 敏感数据存服务器
安全加固
// 生产环境推荐配置 document.cookie = `auth_token=xxx; secure; httponly; samesite=lax; path=/; domain=.example.com; max-age=604800`; // 7天
替代方案选择
- 登录凭证 → HTTP-only Cookie
- 客户端状态 → LocalStorage
- 大数据存储 → IndexedDB
框架集成
// Express 设置 Cookie res.cookie('session', token, { httpOnly: true, secure: process.env.NODE_ENV === 'production', maxAge: 24 * 60 * 60 * 1000, // 1天 }); // 删除 Cookie res.clearCookie('session');
七、面试回答策略
概念分层阐述:
"Cookie 本质是服务端和客户端之间的状态维护机制。核心价值在于实现有状态的 HTTP 通信,弥补协议无状态的缺陷"
安全深度展示:
"我曾通过组合 Secure+HttpOnly+SameSite 三件套,将项目的 XSS 和 CSRF 漏洞报告减少 80%。特别注意在 OAuth 回调中正确处理 SameSite=None 的兼容性"
场景化对比:
"当需要存储 5MB 的用户草稿时,Cookie 完全不适用。我会选择 LocalStorage 配合定期清理,而登录凭证必须用 Http-only Cookie 防止 XSS 窃取"
现代演进认知:
"随着 Chrome 逐步淘汰第三方 Cookie,现在更推荐 Web Storage API + Token 的方案。Cookie 在身份验证领域仍不可替代,但需配合 CSP 等策略加固"
手写代码技巧:
- 先写基础实现
- 逐步添加安全参数
- 解释每个参数的意义
"注意:设置
domain=.example.com
时开头的点号是规范要求,表示包含子域"
💡 面试金句:
"Cookie 是 Web 开发的基石技术,但绝非万能钥匙。现代前端需要精准把握其适用场景,在用户体验与安全性之间找到平衡点,尤其要警惕 '全存 Cookie' 的反模式。"