需根据 content-type 动态设置 cache_valid,因不同资源更新频率差异大:css/js等静态资源可缓存1小时,json等api响应仅缓存10秒;通过 map 指令匹配 $sent_http_content_type 实现差异化配置,并在 proxy_cache_valid 中引用 $cache_ttl 变量生效。

为什么需要根据 Content-Type 动态设置 cache_valid?
静态资源(如 text/css、application/javascript)通常长期不变,适合缓存数天;而 API 响应(如 application/json)可能秒级变动,缓存几秒更安全。Nginx 默认不支持按响应头动态配置 proxy_cache_valid,但借助 map 指令,可基于 $sent_http_content_type(即上游返回的 Content-Type)实现差异化缓存时效控制。
核心配置:用 map 提取 Content-Type 类型并映射缓存时间
在 http 块中定义映射关系,注意必须使用 $sent_http_content_type(不是 $http_content_type,后者是客户端请求头):
map $sent_http_content_type $cache_ttl {
default "5s";
~*^text/ "1h";
~*^application/javascript "1h";
~*^application/css "1h";
~*^image/ "24h";
~*^font/ "7d";
~*^application/json "10s";
~*^application/vnd.api+json "10s";
}
说明:
-
~*表示忽略大小写的正则匹配 - 顺序重要:更具体的规则(如
application/json)建议放在通用规则(如application/)之前,避免被提前匹配 -
default是兜底值,防止未匹配时变量为空导致语法错误
在 location 中启用 proxy_cache 并引用 map 变量
在反向代理 location 块中,将 $cache_ttl 直接用于 proxy_cache_valid:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
proxy_cache my_cache; proxy_cache_valid 200 302 $cache_ttl; proxy_cache_valid 404 1m; proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; <h1>必须开启 header 透传,否则 $sent_http_content_type 不可用</h1><p>proxy_pass_request_headers on; proxy_pass_request_body on;</p><h1>确保上游响应头能被 map 捕获(默认已开启,但显式写出更稳妥)</h1><p>proxy_buffering on;</p>
关键点:
-
proxy_cache_valid支持变量,但仅限于状态码后直接跟变量(如200 302 $cache_ttl),不能写成200 $cache_ttl单独一行 - 务必确认 upstream 返回了
Content-Type头,可通过curl -I验证 - 若上游压缩了响应(如 gzip),Nginx 默认会改写
Content-Type为application/gzip,此时需在 map 中补充匹配或禁用自动重写(gzip_vary off+ 显式设置add_header Vary Accept-Encoding;)
验证与调试技巧
快速确认是否生效:
- 用
curl -I http://your-domain/path.js查看X-Cache和Age头,对比不同资源的缓存命中周期 - 在 Nginx 日志中添加
$sent_http_content_type $cache_ttl到 log_format,实时观察映射结果 - 临时加
add_header X-Cache-TTL $cache_ttl;,浏览器开发者工具 Network 标签页直接查看响应头 - 注意:
map在请求结束、响应头确定后才执行,所以它不影响缓存键(proxy_cache_key),只影响过期策略










