文章中英模式
布魯斯前端面試題目 - 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-TW; _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));