Expires 是什么
Expires 给出资源过期的绝对时刻,是 HTTP/1.0 时代留下的缓存控制手段(RFC 9111 §5.3)。当响应里同时存在 Cache-Control 的 max-age 时,Expires 会被忽略,现代实现一律以 Cache-Control 为准。
老写法为什么容易出事
绝对时刻依赖服务器时钟:时钟漂移或格式写错都可能让缓存立刻失效,或者长期不过期。同时它表达的是时刻而不是时长,任何时钟不一致都会被放大。给静态资源配缓存时,用相对时长表达更可靠。
基本信息
| 名称 | Expires |
|---|---|
| 作用 | 指定绝对过期时刻,格式为 GMT 时间 |
| 规范 | RFC 9111 §5.3 |
| 优先级 | 低于 Cache-Control,同时存在时被忽略 |
| 无效值 | 格式错误或已过去的时刻一律视为已过期 |
典型使用场景
- 兼容老客户端与中间缓存,保留 HTTP/1.0 时代的语义
- 用服务器软件的过期指令一键给静态资源加缓存(通常会同时生成 Expires 与 Cache-Control)
- 排查「配置了缓存但完全不生效」
- 排查缓存时长与预期不一致
配置与观察
配置与观察
location ~* \.(css|js)$ {
expires 7d; # 生成的响应同时带 Expires 与 Cache-Control: max-age
}
# 观察实际头部
# curl -sI https://www.example.com/app.css | grep -iE 'expires|cache-control'缓存头分工
| 头部 | 语义 | 注意事项 |
|---|---|---|
| Expires | 绝对过期时刻 | 依赖时钟,格式错误即被视为已过期 |
| Cache-Control: max-age | 相对秒数 | 现代首选,优先级更高 |
| Cache-Control: no-store | 不允许存储 | 与 Expires 同时出现时以它为准 |
| Last-Modified | 最后修改时间 | 配合条件请求做验证 |
手写 Expires 日期是常见坑:服务器时钟不准或格式错误都会让缓存立即失效。新项目统一使用 Cache-Control 表达新鲜度。
对可能随时更新的页面,应配较短的新鲜度并允许验证,而不是直接设很长的过期时间:前者改版后很快生效,后者要等用户缓存自然过期。
不生效的常见原因
- 响应里同时存在更高优先级的缓存控制字段,旧字段被直接忽略
- 请求方法本身不可缓存,或响应状态并非可缓存状态
- 带了鉴权信息的响应默认不进入共享缓存
- 中间设备按自己的策略改写了头部
验证配置是否真的生效,直接看响应头比看配置文件可靠:配置文件里写了什么不重要,客户端实际收到什么才算数。