按时间做条件请求
If-Modified-Since 让客户端带上自己缓存版本的修改时间,服务器比较资源的 Last-Modified:若此后没有改动就返回 304 Not Modified 且不带正文,从而省掉一次完整传输。它只对 GET 与 HEAD 有效,精度到秒,且时间必须是 GMT 的 IMF-fixdate 格式。现代实现更推荐 ETag 配 If-None-Match。
基本信息
| 方向 | 请求头(响应侧对应 Last-Modified) |
|---|---|
| 规范 | RFC 9110 §13.1.3 |
| 适用方法 | 仅 GET 与 HEAD,其它方法会被忽略 |
| 时间格式 | 必须为 IMF-fixdate 的 GMT 时间,如 Sat, 11 Oct 2026 00:00:00 GMT |
| 优先级 | 与 If-None-Match 同时出现时,If-Modified-Since 被忽略 |
条件头效果对照
| 请求头 | 资源未修改 | 资源已修改 |
|---|---|---|
| If-Modified-Since | 304 Not Modified | 200 带完整正文 |
| If-None-Match | 304 Not Modified | 200 带完整正文 |
| 两者同时出现 | 按 ETag 判定 | 按 ETag 判定 |
| If-Unmodified-Since | 正常执行 | 412 Precondition Failed |
手动条件请求
手动条件请求
curl -si https://www.example.com/ \
-H 'If-Modified-Since: Sat, 11 Oct 2026 00:00:00 GMT' | head -1
# HTTP/1.1 304 Not Modified(若此后未修改)
curl -sI https://www.example.com/ | grep -i -E 'last-modified|etag' # 先取真实时间戳再构造请求典型使用场景
- 静态站点与图床减少重复传输,尤其在大文件与移动网络上收益明显
- 抓包或接口调试时验证服务端是否正确实现缓存协商
- 排查「内容不更新」:确认代理是否错误地返回了 304
- 与 Last-Modified 配合,给不支持 ETag 的老设备提供缓存能力
时间粒度粗且依赖服务端时钟:秒级精度下同一秒内的多次修改无法区分,跨时区或时钟漂移也会造成误判,所以不如 ETag 可靠。
服务端返回 304 时应一并返回 Last-Modified 与 ETag:客户端要更新本地缓存元数据,否则下次条件请求会继续带着过旧的时间戳。
条件请求的判定发生在服务端:若前置代理或 CDN 先一步命中缓存,源站根本收不到这个头,调试时要确认请求头确实透传到了源站,必要时在源站日志里打印。