静态文件缓存时间必须用expires指令配置,因其仅作用于浏览器且仅对匹配的location生效;proxy_cache不适用,因静态文件由Nginx直接提供,未经过proxy_pass。

直接说结论:静态文件缓存时间必须用 expires 指令配,不是 proxy_cache,也不是靠后端返回的 Cache-Control 覆盖——它只作用于浏览器,且仅对匹配的 location 生效。
为什么不能用 proxy_cache 配静态文件缓存时间
proxy_cache 是反向代理级缓存,把上游响应存到磁盘,和浏览器无关;而静态文件(如 .js、.css、.png)通常由 Nginx 自己 root 或 alias 提供,根本没走 proxy_pass,所以 proxy_cache 压根不触发。
常见错误是把 proxy_cache_valid 和 expires 混在一起写,结果 curl -I 看不到 Expires 或 Cache-Control 头,还以为配置没生效。
-
expires只影响响应头,不存文件,也不依赖模块 -
proxy_cache必须配合proxy_pass才起作用 - 两者生效层级不同:一个是客户端缓存策略,一个是服务端中继缓存策略
怎么写一个安全有效的 expires 配置
核心是两点:精准匹配资源类型 + 合理设置时长 + 补充关键响应头。别一股脑全写 expires 1y,HTML 或带版本号的资源会出问题。
Linux AI 服务器 — 将 Linux 服务器转换为本地 AI 推理集群。使用 systemd、NVIDIA CUDA 实现无头 Linux AI,零 GUI 开销。
- 用正则匹配后缀,避免误伤:
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2|ttf)$ - 对长期不变资源(如 CDN 上的构建产物),加
immutable:add_header Cache-Control "public, immutable"; - 对可能高频更新的资源(如未加哈希的
main.css),设短一点,比如expires 1h - 别在
location /或location ~ \.php$里写expires,HTML 和接口响应不该被浏览器强缓存
示例:
location ~* \.(js|css|png|jpg|jpeg|gif|ico|woff2|ttf)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}为什么加了 expires 还看不到响应头
最常见三个原因:
- 配置写在错误的
server块里——比如写了两个server,但你访问的是另一个,检查server_name和实际请求 Host 是否匹配 - 路径没被命中:Nginx 的
location匹配有优先级,^~、=、正则等顺序会影响是否进这个块,用nginx -T查看最终生效的配置树 - 后端(比如 PHP-FPM)返回了
Cache-Control: no-cache,它会覆盖 Nginx 的expires——静态文件如果走fastcgi_pass就属于这种情况,应确保它们由root直接提供
验证和调试的关键动作
别只靠浏览器 F5 刷新看效果,那受开发者工具“禁用缓存”勾选影响。用命令行真实验证:
- 确认请求落到正确 location:
curl -I https://your.site/static/app.js,看返回头有没有Expires和Cache-Control - 检查时间是否合理:对比响应头里的
Date和Expires,差值应等于你设的时长(如expires 1y就该差约 31536000 秒) - 清掉本地缓存干扰:
curl -H "Cache-Control: no-cache" -I https://your.site/static/app.js,排除中间 CDN 或代理干扰 - 改完配置后,一定执行
nginx -t && systemctl reload nginx,reload不等于restart,前者保持连接,后者会断连
真正容易被忽略的是:immutable 虽然能防止带查询参数的重复请求,但它会让浏览器彻底忽略 ETag 和 Last-Modified 协商缓存——如果你依赖这些做细粒度更新,就得权衡要不要加。

















