If-Unmodified-Since 是什么
If-Unmodified-Since 是条件请求头,相当于时间版的 If-Match:只有资源在指定时间之后没有修改过,请求才会被执行;否则返回 412 Precondition Failed(RFC 9110 §13.1.4)。它用于防止「基于旧副本的写入覆盖掉别人刚提交的修改」,属于最简单的乐观并发控制手段。
基本信息
| 名称 | If-Unmodified-Since |
|---|---|
| 方向 | 请求头 |
| 规范 | RFC 9110 §13.1.4 |
| 日期格式 | IMF-fixdate,如 Sat, 11 Oct 2026 08:00:00 GMT |
| 失败响应 | 412 Precondition Failed |
| 优先级 | 与 If-Match 同时出现时忽略本字段 |
| 适用方法 | PUT、POST、DELETE 等会改变状态或内容的请求 |
典型使用场景
- 乐观并发控制:避免覆盖他人修改(先取 Last-Modified,再带条件写入)
- 文档与配置系统:实现简单版本保护,无需先引入 ETag
- 脚本化发布:确认远端文件没被别人改过再上传
- 排障:定位个别写入稳定返回 412 的原因
- 选型对比:判断何时可以用时间戳替代实体标签
- 流水线协作:多人同时触发发布时的冲突检测
防覆盖写入
防覆盖写入
# 1. 先取当前 Last-Modified 作为前置条件
curl -sI https://api.example.com/docs/7 | grep -i last-modified
# last-modified: Sat, 11 Oct 2026 08:00:00 GMT
# 2. 带条件写入:期间被他人改过就返回 412,不会覆盖对方内容
curl -si -X PUT https://api.example.com/docs/7 \
-H 'If-Unmodified-Since: Sat, 11 Oct 2026 08:00:00 GMT' \
--data-binary @doc.md
# HTTP/1.1 412 Precondition Failed # 资源已变更,需重新拉取再改条件请求头对照
| 头部 | 判断依据 | 失败响应 |
|---|---|---|
| If-Match | ETag,精确到内容 | 412 |
| If-Unmodified-Since | 时间戳,精确到秒 | 412 |
| If-None-Match | ETag 判断是否未变化 | 304 或 412 |
| If-Modified-Since | 时间判断是否未变化 | 304 |
时间粒度只到秒,且依赖服务器时钟与 Last-Modified 的可信度;能用 ETag 加 If-Match 就优先用 ETag,它不受时钟与秒级截断影响。
与 If-Match 同时出现时本字段会被忽略——混用两个条件头很容易写出「看起来生效其实没生效」的逻辑。
资源从未被修改过(服务端不返回 Last-Modified)时该头无法生效,写入会直接执行;这是并发保护落空的常见原因。
服务端对「条件不满足」的响应必须是 412,不能静默忽略条件继续写入;否则客户端会以为保护生效,实际已被覆盖。
该头对 GET、HEAD 没有「未修改才执行」的实用意义,它主要服务于会改变资源状态的写入类请求。