首页/网络/协议速查/Expires 绝对过期时间
HTTP 头与缓存70 条

Expires 绝对过期时间

HTTP/1.0 时代的缓存过期时间(绝对 GMT 日期);现代实现中若存在 Cache-Control: max-age 则被忽略。

协议速查网络更新于 2026-10-13

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 表达新鲜度。
对可能随时更新的页面,应配较短的新鲜度并允许验证,而不是直接设很长的过期时间:前者改版后很快生效,后者要等用户缓存自然过期。

不生效的常见原因

  • 响应里同时存在更高优先级的缓存控制字段,旧字段被直接忽略
  • 请求方法本身不可缓存,或响应状态并非可缓存状态
  • 带了鉴权信息的响应默认不进入共享缓存
  • 中间设备按自己的策略改写了头部
验证配置是否真的生效,直接看响应头比看配置文件可靠:配置文件里写了什么不重要,客户端实际收到什么才算数。

易错点

  • 手工推算绝对时间:时钟不准或格式错误会让缓存立刻失效或长期不刷新
  • 同时写 Expires 与 Cache-Control 且两者矛盾:实际以 Cache-Control 为准,另一条形同虚设
  • 给 HTML 设置过长的新鲜度:改版后用户在很长一段时间里看到旧页面
  • 认为设了过期时间就一定会被缓存:可缓存性还要看请求方法、鉴权头与响应状态

数据来源与参考

  • RFC 9111 §5.3 Expires

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌