文章中英模式
布鲁斯前端面试题目 - HTTP Cookie 详解
深入解析HTTP Cookie的工作原理、属性设置、安全考量与应用场景。掌握前端面试中关于Cookie的核心知识,包括SameSite策略和存储方式比较。
文章中英模式
懒得看文章?那就来看视频吧
Cookie是什么?它的工作原理
Cookie是网站存储在用户浏览器中的小型文本数据,浏览器会在后续请求中自动将其发送回服务器。
Cookie工作流程
1. 用户访问网站
↓
2. 服务器回应并设置Cookie
Set-Cookie: user_id=123
↓
3. 浏览器存储Cookie
↓
4. 用户再次访问网站
↓
5. 浏览器自动发送Cookie
Cookie: user_id=123
↓
6. 服务器识别用户
基本工作流程:
- 1. 服务器通过HTTP响应中的Set-Cookie头创建Cookie
- 2. 浏览器接收Cookie并存储
- 3. 浏览器在后续请求中通过Cookie头自动发送Cookie
- 4. 服务器接收Cookie并利用其识别用户或维持状态
// 后端(Node.js)设置Cookie
res.setHeader('Set-Cookie', [
'user_id=abc123; Max-Age=3600',
'session=xyz789; HttpOnly; Secure'
]);
// 前端发送请求时,浏览器会自动带上Cookie
fetch('https://api.example.com/data', {
credentials: 'include', // 跨域请求时需要设置
headers: {
'Content-Type': 'application/json'
}
});
// 浏览器发送的Cookie标头
Cookie: user_id=abc123; session=xyz789; theme=dark; lang=zh-CN; _ga=GA1.2.1234567890.1234567890
Cookie属性与其安全含义
Cookie拥有多个控制其行为和安全性的重要属性:
属性 | 说明 | 安全含义 |
---|---|---|
Expires /Max-Age | 设置Cookie过期时间 | 限制敏感信息存储时间 |
Domain | 指定Cookie可发送至的域名 | 防止不相关子域名访问Cookie |
Path | 指定Cookie可用的URL路径 | 限制同域名下的路径范围 |
Secure | 仅通过HTTPS发送Cookie | 防止中间人拦截Cookie |
HttpOnly | 禁止JavaScript访问Cookie | 防止XSS攻击窃取Cookie |
SameSite | 控制跨站请求时发送Cookie的策略 | 防止CSRF攻击 |
SameSite
是较新的安全属性,有三个可选值,Chrome 80版本后预设为 Lax
:
SameSite值 | 说明 | 适用场景 |
---|---|---|
Strict | 仅同站点请求会发送Cookie | 高安全性要求的应用,如银行网站、后台管理系统 |
Lax | 同站点请求和从外部(如Google搜索)点击链接进入时会发送Cookie,但仅限于GET请求,POST等其他请求方式不会发送 | 大多数网站的平衡选择,Chrome 80后的预设值 |
None | 允许跨站请求发送Cookie(必须同时设置Secure属性) | 需要跨站功能的应用,如第三方嵌入服务 |
实际应用举例:
情境1:网络银行登录Cookie
res.cookie('sessionId', 'abc123', { sameSite: 'strict', secure: true, httpOnly: true });
确保只有用户直接访问银行网站时才发送认证Cookie,防止从其他网站发起的请求带入认证信息
情境2:社交媒体网站
res.cookie('user_session', 'xyz789', { sameSite: 'lax', secure: true, httpOnly: true });
允许用户从外部链接点击进入网站时保持登录状态,但阻止第三方网站的表单提交等操作带入Cookie
情境3:第三方嵌入服务(如评论系统)
res.cookie('embed_token', 'def456', { sameSite: 'none', secure: true });
允许Cookie在跨站请求中发送,使第三方嵌入功能正常工作,但必须通过HTTPS传输以确保基本安全性
Cookie vs localStorage vs sessionStorage
特性 | Cookie | localStorage | sessionStorage |
---|---|---|---|
容量限制 | ~4KB | ~5MB | ~5MB |
过期时间 | 可设置 | 永久 | 会话结束 |
HTTP請求 | 自动发送 | 不发送 | 不发送 |
作用域 | 跨浏览器标签 | 跨浏览器标签 | 仅当前标签 |
适用场景 | 会话管理 服务器需读取 | 持久用户偏好 大量数据缓存 | 表单数据保存 一次性会话数据 |
为什么网站都要显示Cookie同意提示?
近年来,几乎所有网站都会弹出「接受Cookie」的提示框,这不是网站设计的流行趋势,而是因为全球隐私法规的要求,特别是欧盟的《通用数据保护条例》(GDPR)和《电子隐私指令》(ePrivacy Directive)。
法规要求的核心原因
- 用户知情权:法律要求网站必须告知用户他们收集哪些数据、如何使用这些数据。
- 明确同意:在收集非必要Cookie前,必须获得用户的明确同意(opt-in),而非默认收集(opt-out)。
- 选择权:用户有权拒绝非必要的Cookie,网站仍需正常运作。
Cookie同意提示的类型
基本通知型
仅通知用户网站使用Cookie,继续使用网站视为同意。这种方式在某些地区已不符合法规要求。
选择接受/拒绝型
提供接受或拒绝所有Cookie的选项,符合基本法规要求。
分类选择型
允许用户选择接受不同类别的Cookie(如必要、功能性、分析、广告等)。
详细管理型
提供详细的Cookie管理界面,用户可以个别控制每种Cookie。
不同地区的法规差异
地区 | 主要法规 | Cookie同意要求 |
---|---|---|
欧盟 | GDPR, ePrivacy | 明确同意(opt-in),必须提供拒绝选项 |
美国 | CCPA/CPRA (加州) | 知情权和选择退出权(opt-out) |
台湾 | 个人资料保护法 | 需告知并取得同意,但要求较宽松 |
为何全球网站都显示Cookie提示?
即使网站不在欧盟,只要有欧盟用户访问,就需遵守GDPR。由于互联网的全球性,大多数网站选择实施Cookie同意机制以确保全球合规,而非针对不同地区用户显示不同内容。此外,随着全球隐私意识提高,越来越多国家正在制定类似法规。
对开发者而言,Cookie同意机制不仅是法律合规问题,也是尊重用户隐私的表现。实施良好的Cookie政策有助于建立用户信任,同时避免可能的巨额罚款(GDPR下最高可达全球年营收的4%或2000万欧元)。
🔥 常见面试题目
(一) HTTP Cookie的基本原理是什么?它有哪些限制?
解答:HTTP Cookie是网站存储在用户浏览器的小型文本数据。
工作原理:
- 1. 服务器发送Set-Cookie头
- 2. 浏览器保存Cookie
- 3. 后续请求自动带上Cookie头
// 服务器响应
HTTP/1.1 200 OK
Set-Cookie: userId=123; Expires=Wed, 21 Oct 2023 07:28:00 GMT
// 后续请求
GET /api/profile HTTP/1.1
Cookie: userId=123
主要限制:
- 1. 单个Cookie大小约4KB
- 2. 每域名Cookie数量限制(约50-180个)
- 3. 无法跨域访问
- 4. 可被用户删除或禁用
- 5. 受隐私法规限制
- 6. 增加HTTP请求大小
(二) Cookie的SameSite属性有什么作用?不同值有何区别?
解答:SameSite属性控制Cookie是否在跨站请求中发送,主要用于防止CSRF攻击。
Strict
仅同站请求发送
Lax (默認)
同站请求+顶级导航
None
所有跨站请求发送
// 严格模式
Set-Cookie: sessionId=abc123; SameSite=Strict
// 宽松模式 (Chrome默认)
Set-Cookie: sessionId=abc123; SameSite=Lax
// 允许跨站
Set-Cookie: sessionId=abc123; SameSite=None; Secure
(三) Cookie、localStorage和sessionStorage的使用场景分别是什么?
解答:三种存储机制各有适用场景:
Cookie
- 1. 自动发送到服务器
- 2. 身份验证令牌
- 3. 跨标签页共享
- 4. 可设置过期时间
- 5. 容量小(~4KB)
document.cookie = "theme=dark; max-age=86400";
localStorage
- 1. 永久存储
- 2. 用户偏好设置
- 3. 跨标签页共享
- 4. 不发送到服务器
- 5. 容量大(~5MB)
localStorage.setItem("theme", "dark");
sessionStorage
- 1. 仅当前标签页
- 2. 表单暂存数据
- 3. 一次性流程状态
- 4. 标签关闭自动清除
- 5. 容量大(~5MB)
sessionStorage.setItem("formData", JSON.stringify(data));