Last-Modified与If-Modified-Since通过时间比对实现协商缓存:服务器在响应头中按RFC 1123格式(如Mon, 15 Jul 2026 09:45:22 GMT)设置Last-Modified;浏览器强缓存过期后自动携带该值作为If-Modified-Since发起条件请求;服务器比较当前修改时间与该值,仅当前者严格大于后者时返回200,否则返回304。

协商缓存中,Last-Modified 和 If-Modified-Since 是一对配合工作的 HTTP 头字段,它们不独立生效,而是通过“时间比对”完成资源新鲜度验证。
服务器怎么设置 Last-Modified
当浏览器首次请求某个资源(比如 /style.css),服务器在响应头中加入 Last-Modified 字段,值为该资源在服务端的最后修改时间,格式必须严格符合 RFC 1123 标准:
-
✅ 正确示例:
Last-Modified: Mon, 15 Jul 2026 09:45:22 GMT -
❌ 错误示例:
Last-Modified: 2026-07-15T09:45:22Z(浏览器可能忽略)
这个时间通常来自文件系统元数据(如 fs.stat().mtime.toUTCString()),不能简单用 new Date().toString() 拼接。
浏览器怎么发送 If-Modified-Since
当强缓存(如 Cache-Control: max-age=3600)过期后,浏览器不会直接发全新请求,而是自动带上 If-Modified-Since 请求头,其值就是上次响应中收到的 Last-Modified 时间:
- 请求头:
If-Modified-Since: Mon, 15 Jul 2026 09:45:22 GMT - 这个动作完全由浏览器自动完成,无需 HTML 或 JavaScript 干预
服务器怎么校验并返回结果
服务器收到带 If-Modified-Since 的请求后,执行以下判断逻辑:
- 读取当前资源的真实最后修改时间(同样需转为 GMT 字符串)
- 比较:若当前时间 >
If-Modified-Since时间 → 资源已更新 → 返回200 OK+ 新内容 - 比较:若当前时间 ≤
If-Modified-Since时间 → 资源未变 → 返回304 Not Modified,响应体为空
注意:比较是“大于”才认为有更新,等于或小于都走 304。这也是为什么秒级精度下,同一秒内多次修改可能被跳过。
实际效果与常见限制
这套机制能减少重复传输,但存在几个关键约束:
- 只支持秒级精度,无法感知毫秒级变更
- 依赖服务器和客户端时钟同步,时钟偏差可能导致误判
- 文件未改内容但修改时间被更新(如拷贝、部署覆盖),会触发不必要的 200 响应
- 当与
ETag同时存在时,ETag优先校验,Last-Modified不再参与比对


















