Cookie 的 Expires 和 Max-Age 有什么区别?
核心结论
Max-Age 优先于 Expires。两者同时设置时,浏览器只认 Max-Age。Expires 是 HTTP/1.0 的产物,用绝对时间;Max-Age 是 HTTP/1.1 引入的,用相对秒数,不受客户端时钟偏差影响。现代开发应优先使用 Max-Age,仅在需要兼容 IE 时同时设置 Expires 作为降级。
两者的本质区别
| 维度 | Expires | Max-Age |
|---|---|---|
| 规范来源 | HTTP/1.0 (Netscape 草案) | HTTP/1.1 (RFC 6265) |
| 时间类型 | 绝对时间 (GMT 字符串) | 相对时间 (秒数) |
| 优先级 | 低 | 高 |
| 时钟依赖 | 依赖客户端本地时间 | 不依赖,从收到 Cookie 起算 |
| 浏览器兼容 | 全部浏览器 | IE6/7/8 不支持 |
| 典型值 | Wed, 09 Jun 2026 10:18:14 GMT | 3600 |
关键差异在于时钟依赖:Expires 指定“到什么时刻过期”,依赖客户端系统时钟。如果用户电脑时间比服务器快几小时,Cookie 可能提前过期;慢几小时则延迟过期。Max-Age 指定“从现在起还能活多久”,浏览器收到 Cookie 后自己倒计时,不受时钟偏移影响。
Expires 的用法
javascript// 设置 7 天后过期 const expires = new Date(); expires.setDate(expires.getDate() + 7); document.cookie = "token=abc; Expires=" + expires.toUTCString(); // 设置过去的日期 → 立即删除 Cookie document.cookie = "token=abc; Expires=Thu, 01 Jan 1970 00:00:00 GMT";
时间格式必须是 UTC (GMT) 字符串。toUTCString() 生成正确格式,toISOString() 生成的格式浏览器不一定识别。
Max-Age 的用法
javascript// 1 小时后过期 document.cookie = "token=abc; Max-Age=3600"; // 1 天后过期 document.cookie = "token=abc; Max-Age=86400"; // 立即删除 document.cookie = "token=abc; Max-Age=0"; // 会话 Cookie(浏览器关闭即删除)——不设置 Max-Age 和 Expires 即可 document.cookie = "sessionId=abc";
Max-Age 的特殊值:0 表示立即删除;负数也表示立即删除(但部分浏览器行为不一致,推荐用 0);不设置则变成会话 Cookie。
优先级规则
两者同时出现时,Max-Age 优先:
javascript// 同时设置,Max-Age 生效,Cookie 在 1 小时后过期 document.cookie = "token=abc; Expires=Wed, 09 Jun 2026 10:18:14 GMT; Max-Age=3600";
这个优先级是 RFC 6265 明确规定的。IE6/7/8 不识别 Max-Age,会回退使用 Expires——这也是为什么兼容旧浏览器时要同时设置两者。
追问:服务器端怎么设置?
前端 document.cookie 只能设置非 HttpOnly 的 Cookie。实际项目中 Cookie 过期时间主要由服务端通过 Set-Cookie 响应头控制:
httpSet-Cookie: token=abc; Max-Age=3600; Path=/; HttpOnly; Secure; SameSite=Strict
Node.js Express 示例:
javascriptres.cookie("authToken", token, { maxAge: 3600 * 1000, // 注意:Express 的 maxAge 单位是毫秒 httpOnly: true, secure: true, sameSite: "strict", path: "/" });
注意坑:Express 的 maxAge 选项单位是毫秒,而 HTTP 头中的 Max-Age 单位是秒。Express 内部会自动转换。
追问:删除 Cookie 的正确姿势
删除 Cookie 必须满足三个条件:名称、域名(Domain)、路径(Path) 全部匹配,否则浏览器会创建一个同名新 Cookie 而非删除旧的。
javascript// 删除时必须与设置时的 Path 和 Domain 一致 document.cookie = "token=abc; Max-Age=0; Path=/; Domain=example.com";
实际开发建议
- 优先用 Max-Age:不受客户端时钟影响,计算简单,是 RFC 6265 推荐方式
- 兼容旧浏览器时同时设置两者:Max-Age 为主,Expires 做降级
- 敏感信息用短过期:认证 Token 建议几小时级别,配合刷新机制
- “记住我”用长过期:30 天左右,但务必配合 HttpOnly + Secure + SameSite
- 不要依赖 Expires 做精确过期:用户设备时钟不可控