前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库Last-Modified ETag 对比 条件请求
HTHTTP缓存与代理

HTTP 条件请求中 Last-Modified 和 ETag 同时存在时客户端该用哪个,秒级精度会带来什么问题?

两者同时出现时客户端应优先使用 ETag,因为 ETag 是更精确的验证器,能识别秒级精度内的多次变更;Last-Modified 只精确到秒,可能漏掉同一秒内的修改。

前端进阶之旅 · 一题精讲更新于 2026.09.05
HTTP#缓存与代理#缓存
先看核心答案
理解线索

验证器与时间精度

  1. ETag不透明字符串,精确标识版本
  2. Last-Modified日期时间,秒级精度
  3. 条件请求用验证器判断资源是否变化

服务器应同时提供,但客户端优先用 ETag。

核心回答

先记住这个答案

当响应同时包含 Last-Modified 和 ETag 时,条件请求应优先使用 ETag(即发送 If-None-Match),因为 ETag 能精确标识资源版本,不受时间粒度限制。Last-Modified 只有秒级精度,如果资源在一秒内被修改多次,其值可能不变,导致缓存误判为未修改而返回过时内容。因此客户端应依赖 ETag 进行验证,Last-Modified 仅作为兜底或在无 ETag 时使用。

  • ETag 优先于 Last-Modified
  • 秒级精度漏检同秒修改
  • ETag 可精确到任意粒度

验证器的比较规则

HTTP 验证器分为强验证器和弱验证器。ETag 默认是强验证器,只要字节内容变化,ETag 就必须变化;而 Last-Modified 是时间戳,只能精确到秒。当资源在 1 秒内连续两次修改,第二次修改的 Last-Modified 可能与第一次相同(若在同一秒完成),导致条件请求误判为未修改。

RFC 9110 定义 ETag 比较时,强验证器要求字节完全一致,弱验证器(W/ 前缀)允许语义等价。Last-Modified 比较时使用 HTTP 日期格式,必须精确到秒。因此 ETag 能提供更可靠的版本验证,尤其适合频繁更新的资源。

秒级精度漏检的实例

某 API 返回 JSON 数据,服务器快速更新:09:00:00.500 写入数据 A,09:00:00.900 写入数据 B。Last-Modified 均显示为 09:00:00,因为时间戳只到秒。客户端缓存了 A 的响应,携带 If-Modified-Since: 09:00:00 发起请求,服务器发现 Last-Modified 不大于该时间,返回 304,客户端继续使用 A,但实际数据已是 B。

若响应带有 ETag,服务器生成 ETag 为 "v1" 和 "v2",客户端携带 If-None-Match: "v1",服务器比较发现不匹配,返回 200 和新数据,正确更新。此场景说明 ETag 的精度优势直接避免数据过期。

适用前提与限制

ETag 优先的前提是服务器正确实现 ETag 生成规则,且资源每次变化时 ETag 都更新。若服务器使用弱 ETag(W/ 前缀),它可能不随字节变化而变化(如语义等价),此时强校验能力降低,但仍比 Last-Modified 可靠。

Last-Modified 并非全无用处:当客户端只存储了 Last-Modified 而没有 ETag(如旧缓存)时,可退化为 If-Modified-Since。另外,某些服务器可能因性能原因不生成 ETag,此时只能依赖时间。但设计上应尽量提供 ETag,并确保其唯一性。

回答前,多想一步

容易答错的地方

认为 Last-Modified 足够精确
Last-Modified 只精确到秒,无法区分 1 秒内的多次修改。若认为它接近实时,会设计出过期缓存风险的方案。正确做法是依赖 ETag 或在文件内容变化时同步更新时间戳。
同时发送两个条件头
RFC 9110 规定当 If-None-Match 存在时,服务器必须忽略 If-Modified-Since。因此不必同时发送,否则只是增加请求头大小,且可能因两者值不一致导致歧义。客户端应只发送 If-None-Match。
试着用自己的话回答

面试官还会怎么问?

If-Modified-Since 和 If-None-Match 同时出现时服务器如何处理?

根据 RFC 9110,If-None-Match 优先,服务器必须忽略 If-Modified-Since。所以实际以 If-None-Match 为准,避免冲突。

强 ETag 和弱 ETag 对条件请求有何影响?

强 ETag 用于 If-Match / If-None-Match 时可做字节级精确比较;弱 ETag 只能做语义等价比较,因此不能用于 If-Range 等要求强验证的场合。

启发式缓存中 Last-Modified 的作用是什么?

当响应没有明确新鲜度信息时,缓存可基于 Last-Modified 估算新鲜期(通常为 10%),但该方法不精确,只作为兜底策略。

从一道题,走向一组知识

把知识连起来

缓存与代理

服务器没有返回 Expires 和 max-age 时,HTTP 缓存能否根据 Last-Modified 推断新鲜期,风险是什么?

同属「缓存与代理」专题,接着看 HTTP 启发式缓存 heuristic freshness Last-Modified 在具体场景中的处理方式。

缓存与代理

HTTP 缓存如何计算响应的当前 Age,经过多级代理时 Age 头与 Date 头怎样参与计算?

同属「缓存与代理」专题,接着看 HTTP Age 头计算 多级代理 Date RFC9111 在具体场景中的处理方式。

参考资料

  • RFC 9110 - HTTP Semantics

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. 验证器的比较规则
  3. 秒级精度漏检的实例
  4. 适用前提与限制
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑