Cookie 操作 #
什么是 Cookie? #
Cookie 是存储在浏览器中的小型文本数据,用于在客户端和服务器之间传递状态信息。
text
┌─────────────────────────────────────────────────────────────┐
│ Cookie 工作原理 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 浏览器 ◄──────────────────────────────────► 服务器 │
│ │ │ │
│ │ 1. 首次请求 │ │
│ │ ─────────────────────────────────────────► │ │
│ │ │ │
│ │ 2. 响应 + Set-Cookie 头 │ │
│ │ ◄───────────────────────────────────────── │ │
│ │ │ │
│ │ 3. 存储 Cookie │ │
│ │ │ │
│ │ 4. 后续请求自动携带 Cookie │ │
│ │ ─────────────────────────────────────────► │ │
│ │
└─────────────────────────────────────────────────────────────┘
Cookie 的特点 #
text
┌─────────────────────────────────────────────────────────────┐
│ Cookie 特点 │
├─────────────────────────────────────────────────────────────┤
│ 大小限制:单个 Cookie 最大 4KB │
│ 数量限制:每个域名最多 20-50 个 Cookie │
│ 自动发送:每次 HTTP 请求自动携带 │
│ 过期时间:可设置过期时间 │
│ 作用域:可设置域名和路径限制 │
│ 安全性:支持 HttpOnly、Secure、SameSite │
└─────────────────────────────────────────────────────────────┘
基础函数 #
setCookie(name, value, days) #
设置 Cookie。
javascript
export const setCookie = (name, value, days) => {
let expires = '';
if (days) {
const date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = '; expires=' + date.toUTCString();
}
document.cookie = name + '=' + value + expires + '; path=/';
};
使用示例 #
javascript
import { setCookie } from './utils/cookie';
setCookie('token', 'abc123xyz', 7);
setCookie('user', 'John', 30);
setCookie('preference', 'dark', 365);
setCookie('session', 'xyz789');
设置选项 #
javascript
const setCookieAdvanced = (name, value, options = {}) => {
const {
days = 0,
path = '/',
domain = '',
secure = false,
sameSite = 'Lax'
} = options;
let cookie = `${name}=${encodeURIComponent(value)}`;
if (days) {
const date = new Date();
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
cookie += `; expires=${date.toUTCString()}`;
}
cookie += `; path=${path}`;
if (domain) {
cookie += `; domain=${domain}`;
}
if (secure) {
cookie += '; Secure';
}
cookie += `; SameSite=${sameSite}`;
document.cookie = cookie;
};
setCookieAdvanced('token', 'abc123', {
days: 7,
secure: true,
sameSite: 'Strict'
});
getCookie(name) #
获取 Cookie 值。
javascript
export const getCookie = (name) => {
const reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)');
const match = document.cookie.match(reg);
return match ? match[2] : null;
};
使用示例 #
javascript
import { getCookie } from './utils/cookie';
const token = getCookie('token');
const user = getCookie('user');
if (token) {
console.log('用户已登录');
} else {
console.log('用户未登录');
}
获取所有 Cookie #
javascript
const getAllCookies = () => {
const cookies = {};
document.cookie.split(';').forEach(cookie => {
const [name, value] = cookie.trim().split('=');
if (name) {
cookies[name] = decodeURIComponent(value || '');
}
});
return cookies;
};
getAllCookies();
deleteCookie(name) #
删除 Cookie。
javascript
export const deleteCookie = (name) => {
document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/';
};
使用示例 #
javascript
import { deleteCookie } from './utils/cookie';
deleteCookie('token');
deleteCookie('user');
deleteCookie('session');
删除指定域名的 Cookie #
javascript
const deleteCookieWithDomain = (name, domain, path = '/') => {
document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=${path}; domain=${domain}`;
};
deleteCookieWithDomain('token', '.example.com');
Cookie 属性详解 #
1. Expires / Max-Age #
javascript
const setCookieWithExpires = (name, value, expiresDate) => {
document.cookie = `${name}=${value}; expires=${expiresDate.toUTCString()}; path=/`;
};
const setCookieWithMaxAge = (name, value, maxAge) => {
document.cookie = `${name}=${value}; max-age=${maxAge}; path=/`;
};
const oneHourLater = new Date(Date.now() + 60 * 60 * 1000);
setCookieWithExpires('session', 'abc', oneHourLater);
setCookieWithMaxAge('session', 'abc', 3600);
2. Path #
javascript
setCookie('app1', 'value1', 1);
setCookie('app2', 'value2', 1);
document.cookie = 'global=value; path=/';
document.cookie = 'admin=value; path=/admin';
3. Domain #
javascript
document.cookie = 'main=value; path=/; domain=example.com';
document.cookie = 'sub=value; path=/; domain=sub.example.com';
document.cookie = 'wildcard=value; path=/; domain=.example.com';
4. Secure #
javascript
const setSecureCookie = (name, value, days) => {
let cookie = `${name}=${value}; path=/`;
if (days) {
const date = new Date();
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
cookie += `; expires=${date.toUTCString()}`;
}
cookie += '; Secure';
document.cookie = cookie;
};
setSecureCookie('secureToken', 'abc123', 7);
5. HttpOnly #
javascript
// 注意:HttpOnly 只能通过服务器设置
// HTTP 响应头示例:
// Set-Cookie: token=abc123; HttpOnly; Secure; SameSite=Strict
6. SameSite #
javascript
const setCookieWithSameSite = (name, value, days, sameSite = 'Lax') => {
let cookie = `${name}=${value}; path=/`;
if (days) {
const date = new Date();
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
cookie += `; expires=${date.toUTCString()}`;
}
cookie += `; SameSite=${sameSite}`;
document.cookie = cookie;
};
setCookieWithSameSite('token', 'abc', 7, 'Strict');
setCookieWithSameSite('session', 'xyz', 1, 'Lax');
setCookieWithSameSite('tracking', '123', 30, 'None');
SameSite 值对比 #
| 值 | 描述 | 适用场景 |
|---|---|---|
| Strict | 完全禁止第三方 Cookie | 敏感操作 |
| Lax | 允许 GET 请求携带 | 大多数场景(默认) |
| None | 允许跨站发送 | 需要 Secure 配合 |
实际应用场景 #
1. 用户登录状态管理 #
javascript
import { setCookie, getCookie, deleteCookie } from './utils/cookie';
class AuthManager {
constructor() {
this.tokenKey = 'auth_token';
this.userKey = 'user_info';
}
login(token, user, rememberMe = false) {
const days = rememberMe ? 30 : 1;
setCookie(this.tokenKey, token, days);
setCookie(this.userKey, JSON.stringify(user), days);
}
logout() {
deleteCookie(this.tokenKey);
deleteCookie(this.userKey);
}
isLoggedIn() {
return !!getCookie(this.tokenKey);
}
getToken() {
return getCookie(this.tokenKey);
}
getUser() {
const userStr = getCookie(this.userKey);
return userStr ? JSON.parse(userStr) : null;
}
}
const auth = new AuthManager();
auth.login('abc123', { id: 1, name: 'John' }, true);
2. 用户偏好设置 #
javascript
import { setCookie, getCookie } from './utils/cookie';
class PreferenceManager {
constructor() {
this.key = 'user_preferences';
}
get() {
const prefStr = getCookie(this.key);
return prefStr ? JSON.parse(prefStr) : this.getDefaults();
}
set(preferences) {
const current = this.get();
const updated = { ...current, ...preferences };
setCookie(this.key, JSON.stringify(updated), 365);
}
getDefaults() {
return {
theme: 'light',
language: 'zh-CN',
fontSize: 'medium',
notifications: true
};
}
reset() {
setCookie(this.key, JSON.stringify(this.getDefaults()), 365);
}
}
const prefs = new PreferenceManager();
prefs.set({ theme: 'dark' });
3. 多语言切换 #
javascript
import { setCookie, getCookie } from './utils/cookie';
class LanguageManager {
constructor() {
this.key = 'language';
this.defaultLang = 'zh-CN';
this.supportedLangs = ['zh-CN', 'en-US', 'ja-JP'];
}
get() {
const saved = getCookie(this.key);
if (saved && this.supportedLangs.includes(saved)) {
return saved;
}
return this.detectBrowserLanguage() || this.defaultLang;
}
set(lang) {
if (this.supportedLangs.includes(lang)) {
setCookie(this.key, lang, 365);
window.location.reload();
}
}
detectBrowserLanguage() {
const browserLang = navigator.language || navigator.userLanguage;
return this.supportedLangs.find(lang => browserLang.startsWith(lang.split('-')[0]));
}
}
const langManager = new LanguageManager();
langManager.set('en-US');
4. A/B 测试 #
javascript
import { setCookie, getCookie } from './utils/cookie';
class ABTestManager {
constructor() {
this.key = 'ab_test';
}
getVariant(testName, variants = ['A', 'B']) {
const tests = this.getAll();
if (tests[testName]) {
return tests[testName];
}
const variant = variants[Math.floor(Math.random() * variants.length)];
tests[testName] = variant;
setCookie(this.key, JSON.stringify(tests), 30);
return variant;
}
getAll() {
const str = getCookie(this.key);
return str ? JSON.parse(str) : {};
}
}
const abTest = new ABTestManager();
const variant = abTest.getVariant('button_color', ['red', 'blue', 'green']);
console.log(`用户分组: ${variant}`);
安全最佳实践 #
1. 敏感数据处理 #
javascript
const setSecureCookie = (name, value, options = {}) => {
const {
days = 1,
secure = true,
sameSite = 'Strict'
} = options;
let cookie = `${name}=${encodeURIComponent(value)}; path=/`;
if (days) {
const date = new Date();
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
cookie += `; expires=${date.toUTCString()}`;
}
if (secure && location.protocol === 'https:') {
cookie += '; Secure';
}
cookie += `; SameSite=${sameSite}`;
document.cookie = cookie;
};
2. Cookie 加密 #
javascript
import md5 from './md5';
const setEncryptedCookie = (name, value, secret, days) => {
const encrypted = btoa(value);
const signature = md5(encrypted + secret);
setCookie(name, `${encrypted}.${signature}`, days);
};
const getDecryptedCookie = (name, secret) => {
const cookieValue = getCookie(name);
if (!cookieValue) return null;
const [encrypted, signature] = cookieValue.split('.');
const expectedSignature = md5(encrypted + secret);
if (signature !== expectedSignature) {
console.error('Cookie 签名验证失败');
return null;
}
return atob(encrypted);
};
3. 防止 XSS 攻击 #
javascript
const safeSetCookie = (name, value, days) => {
const safeName = encodeURIComponent(name);
const safeValue = encodeURIComponent(value);
setCookie(safeName, safeValue, days);
};
const safeGetCookie = (name) => {
try {
const value = getCookie(encodeURIComponent(name));
return value ? decodeURIComponent(value) : null;
} catch (e) {
console.error('Cookie 读取错误:', e);
return null;
}
};
Cookie vs 其他存储方式 #
| 特性 | Cookie | localStorage | sessionStorage |
|---|---|---|---|
| 大小限制 | 4KB | 5MB | 5MB |
| 过期时间 | 可设置 | 永久 | 会话结束 |
| HTTP 请求 | 自动携带 | 不携带 | 不携带 |
| 跨标签页 | 共享 | 共享 | 隔离 |
| 安全属性 | 丰富 | 一般 | 一般 |
下一步 #
现在你已经掌握了 Cookie 操作,接下来学习 日期时间处理,了解日期格式化和时间计算!
最后更新:2026-04-04