Nginx 无内置 expires_excluded_types 指令,但可通过 map + $sent_http_content_type 精准排除类型缓存,或用 location 优先级覆盖、反向代理中结合 proxy_ignore_headers 与 map 实现等效效果。

Nginx 本身没有 expires_excluded_types 这个内置指令,它不是 Nginx 的原生命令,也不能像 Apache 那样通过类似 ExpiresExcludedTypes 直接排除某些 MIME 类型。但你可以用标准、可靠的方式实现等效效果:精准控制哪些类型不缓存(即“排除”),核心思路是——让这些动态类型匹配到一个强制禁用缓存的规则,优先级高于通用缓存规则。
下面分三类实用场景说明怎么做:
✅ 按响应内容类型(最推荐):用 map + $sent_http_content_type 动态排除
这是最准确的方式,因为真实 Content-Type 由后端决定(比如 PHP 返回 text/html; charset=utf-8,API 返回 application/json),比文件后缀更可信。
在 http{} 块中定义:
map $sent_http_content_type $expires_time {
default "epoch"; # 默认不缓存(强制过期)
~*^text/html "0"; # HTML 禁用缓存(no-cache 行为)
~*^application/json "0";
~*^application/xml "0";
~*^text/plain "0";
~*^text/css "1h";
~*^application/javascript "1h";
~*^image/ "1y";
}然后在 location 中启用:
location / {
expires $expires_time;
add_header Cache-Control "public";
}? 关键点:
"epoch"和"0"都会让浏览器视为已过期,触发Cache-Control: no-cache或清空Expires头;把动态类型(如text/html,application/json)显式映射为"0"或"epoch",就实现了“排除缓存”。
✅ 按请求路径或后缀:用 location 优先级覆盖
如果你知道动态资源固定走某些路径(如 /api/, /admin/, .php),可用高优先级 location 提前拦截并禁用缓存:
# 高优先级:先匹配动态路径,禁用缓存
location ^~ /api/ {
expires -1;
add_header Cache-Control "no-store, must-revalidate";
}
location ~ \.php$ {
expires -1;
add_header Cache-Control "no-cache, no-store";
}
# 再匹配静态资源,启用缓存(低优先级,会被上面覆盖)
location ~* \.(js|css|png|jpg|woff2|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}⚠️ 注意:正则
location ~优先级低于前缀location ^~和精确location =,所以/api/xxx一定先命中^~ /api/,不会误入静态规则。
✅ 对反向代理场景:强制忽略后端 Cache-Control 并重写
当 Nginx 作为反向代理时,后端可能返回 Cache-Control: no-cache,但你想对部分类型“强行缓存”——反之,若后端错误地返回了 public, max-age=3600,而你想排除某些类型(如 JSON 接口),就得覆盖它:
location / {
proxy_pass http://backend;
proxy_ignore_headers Cache-Control Expires Set-Cookie; # 忽略后端缓存头
proxy_cache_valid 200 201 204 301 302 10m;
# 动态类型单独处理:匹配响应头,再设 expires
proxy_hide_header Cache-Control;
proxy_hide_header Expires;
# 利用 map + proxy_cache_valid 组合(需配合 proxy_cache)
# 或更直接:用 add_header 覆盖(但注意 expires 会自动设 Cache-Control)
expires -1;
}
# 更细粒度:按响应类型差异化
map $upstream_http_content_type $proxy_cache_ttl {
default 0;
~*^application/json 0;
~*^text/html 0;
~*^image/ 1h;
}然后在 location 中:
proxy_cache_valid 200 201 204 301 302 $proxy_cache_ttl;
这种方式适合需要代理缓存 + 类型排除的混合场景。
不复杂但容易忽略


















