Nginx 不提供 if_unmodified_since 指令,但完整支持 HTTP 的 If-Unmodified-Since 请求头,用于条件性操作(如防止覆盖),通过 $http_if_unmodified_since 变量识别,可结合 Last-Modified 实现 412 响应或透传至后端。

Nginx 本身没有 if_unmodified_since 这个配置指令,它只是完整支持 HTTP 协议定义的 If-Unmodified-Since 请求头。这个头不是用来“开启缓存”的,而是做条件性资源操作控制——比如防止并发写入冲突、确保客户端拿到的是未被覆盖的原始版本,尤其在文件同步、断点续传、CDN回源协同等场景中很关键。
If-Unmodified-Since 是什么?
它是客户端发来的标准 HTTP 请求头,格式类似:
If-Unmodified-Since: Wed, 21 Oct 2024 07:28:00 GMT
语义是:“请只在目标资源自该时间点之后从未被修改过的情况下,才执行本次请求(如返回内容、接受上传);否则返回 412 Precondition Failed”。
这个判断依据通常是响应头中的 Last-Modified 值。Nginx 不自动比对,但提供了变量和机制让你自己实现逻辑。
如何在 Nginx 中识别并响应 If-Unmodified-Since
Nginx 把这个头解析后存为内置变量 $http_if_unmodified_since,你可以用它做条件判断:
-
检查是否携带该头:
if ($http_if_unmodified_since) { # 进入条件分支 } -
结合
Last-Modified做简单拦截(适用于静态文件服务):location /files/ { add_header Last-Modified $date_gmt; if ($http_if_unmodified_since) { # 注意:这里仅作示意,真实时间比对需更严谨(时区、格式、精度) return 412; } }
⚠️ 注意:if 在 location 外不可用于重写,且不推荐嵌套复杂逻辑。生产环境更稳妥的做法是透传该头给后端应用处理。
在文件同步场景下的典型用法
比如一个客户端要上传新版本文件,但希望“仅当服务端当前文件没被别人改过”才允许覆盖——这就需要 If-Unmodified-Since 配合 PUT 或 POST 请求。
-
客户端先
GET /doc.pdf,拿到响应头:Last-Modified: Tue, 05 May 2026 10:30:00 GMT
-
然后发起带条件的上传:
PUT /doc.pdf If-Unmodified-Since: Tue, 05 May 2026 10:30:00 GMT
-
Nginx 可以:
- 直接透传该头到后端(关闭 proxy_ignore_headers);
- 或者由 Nginx 自己比对(需配合
map+ 时间格式标准化); - 若检测到文件已被修改(比如
stat()获取的 mtime > 请求头时间),就return 412。
这样就能避免“静默覆盖”,保障最终一致性。
与缓存模块和反向代理的协作要点
-
ngx_http_not_modified_module会自动处理If-Modified-Since和If-Unmodified-Since,但仅限于返回304 Not Modified或直接响应体,不主动返回412; - 启用
proxy_cache时,默认会剥离If-Unmodified-Since等条件头,不转发给上游——必须显式配置:proxy_pass_request_headers on; proxy_set_header If-Unmodified-Since $http_if_unmodified_since;
- 如果你用 Nginx 做 CDN 边缘节点,又需要源站校验版本,就必须确保这个头能穿透多层代理到达业务后端。
不复杂但容易忽略











