Nginx对.js/.css/.png等静态文件启用浏览器缓存应使用expires和add_header Cache-Control,而非proxy_cache;前者通过响应头控制客户端缓存,后者为服务端磁盘缓存,二者职责不同、不可混用。

只对 .js/.css/.png 等静态文件启用浏览器缓存
这不是 proxy_cache 的事,而是用 expires 和 add_header Cache-Control 控制浏览器行为。Nginx 不会把这些文件存到磁盘,只是告诉浏览器“你本地留着用就行”。
- 在
location块里用正则匹配后缀:location ~* \.(js|css|png|jpg|gif|ico|woff2|svg)$ - 加
expires 1y;:生成Cache-Control: max-age=31536000和Expires头 - 强烈建议加
add_header Cache-Control "public, immutable";:避免带查询参数(如app.js?v=2)被当成新资源重新请求 - 别在
location /或location ~ \.php$里套这个——HTML 和动态接口不该缓存那么久 - 注意优先级:如果后端 PHP/Node 返回了
Cache-Control: no-cache,Nginx 的expires会被覆盖,此时需加proxy_ignore_headers Cache-Control;(仅限反向代理场景)
对 /static/ 下所有文件统一设长缓存
用路径前缀比后缀更可靠,尤其当文件没扩展名或 CDN 重写 URL 时。
location ^~ /static/ { expires 30d; add_header Cache-Control "public, immutable"; }-
^~表示前缀匹配且优先级高于正则,避免被其他location ~ \.php规则劫持 - 确保
/static/路径真实存在且由 Nginx 直接提供(非proxy_pass),否则expires不生效 - 如果 /static/ 实际指向后端服务(比如 Python static view),那得改用
proxy_cache,而不是expires
proxy_cache 只缓存特定路径(如 /api/v1/assets)
这是服务端缓存,把响应体写进磁盘,和浏览器无关。想让它生效,必须同时满足路径匹配 + 状态码允许 + 缓存键唯一。
Linux系统管理专家,覆盖12大模块:用户权限、SSH、存储、网络、systemd、防火墙、日志监控、备份恢复、TLS证书、Ansible、容器、IaC。提供配置、验证、加固、监控、备份、自动化、故障排查、回滚闭环。关键词:useradd、sudo、sshd_config、chmod、SEL...
- 先定义缓存区:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=assets_cache:10m max_size=500m inactive=1h; - 在对应
location里启用:location /api/v1/assets { proxy_pass http://backend; proxy_cache assets_cache; } - 显式指定状态码缓存规则:
proxy_cache_valid 200 206 301 302 1h;(漏掉 206 会导致视频分片缓存失败) - 务必包含查询参数:
proxy_cache_key "$scheme$request_method$host$request_uri$is_args$args";,否则/api/v1/assets?id=123和?id=456会共用一个缓存项 - 检查权限:
/var/cache/nginx目录属主必须是 Nginx worker 用户(通常是www-data或nginx),否则X-Cache-Status永远是MISS
缓存不生效时最先查哪几件事
90% 的“配置写了但没用”问题都卡在这几个点上,别急着改配置,先看日志和响应头。
- 用
curl -I http://yoursite/static/logo.png看有没有Cache-Control或Expires——没有就是location没匹配上 - 用
curl -I http://yoursite/api/v1/assets看X-Cache-Status值:是MISS就说明没进缓存区,重点查proxy_cache_path权限和proxy_cache_valid是否覆盖了实际返回的状态码 - 查 Nginx error log:
tail -f /var/log/nginx/error.log,常见报错如open() "/var/cache/nginx/..." failed (13: Permission denied) - 确认后端是否返回了
Set-Cookie或Authorization头——默认情况下 Nginx 会跳过缓存,需加proxy_ignore_headers Set-Cookie;才行
真正容易被忽略的不是语法,而是缓存层级的职责混淆:浏览器缓存靠 expires,服务端缓存靠 proxy_cache,两者不能互相替代,也不能在同一个 location 里混着配。配错一层,整条链路就断了。

















