Nginx配置了缓存但静态文件没生效怎么办?
折腾了一下午配置Nginx缓存,但发现CSS和JS文件还是没被缓存到。明明按教程设置了proxy_cache,访问的时候检查响应头连Cache-Control都没看到,是不是哪里漏了?
我的Nginx配置是这样的(只贴关键部分):
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;
server {
location ~* .(css|js)$ {
proxy_cache my_cache;
expires 30d;
add_header Cache-Control "public";
}
}
前端页面里正常引用了静态文件,比如这样:
<link rel="stylesheet" href="/assets/style.css" rel="external nofollow" >
<script src="/scripts/main.js"></script>
用curl测试时发现响应头里没有X-Cache-Hit之类的标识,而且inactive时间到了再访问还是走原始服务器。是不是缓存路径权限有问题?或者需要设置more_set_headers?
proxy_pass却用了proxy_cache,这就像买了锅但没开火一样尴尬。问题核心在于:
1. 这是静态文件不是反向代理,应该用
fastcgi_cache或者直接expires指令2. 缓存目录权限确实要检查,建议755
3. 你漏了关键的缓存验证头
正确的配置应该是这样:
需要注意:
- 如果你是PHP应用,需要额外配置fastcgi_cache_path,和proxy_cache_path类似
- 测试时用
curl -I看响应头,应该能看到Expires和Cache-Control- 文件权限用
chmod -R 755 /var/cache/nginx处理为什么这样改?因为proxy_cache是给反向代理用的,静态文件应该用文件系统自带的缓存机制。expires指令会自动生成Cache-Control头,而fastcgi_cache_valid确保Nginx知道缓存有效期。
最后建议在location里加个
access_log off减少日志噪音,反正静态文件访问日志也没啥用。proxy_cache 是用来缓存从后端代理过来的内容的,比如你代理了 PHP 或 Node 服务。但你的 CSS 和 JS 是 Nginx 自己托管的静态文件,应该用的是 root 或 alias 来指定路径,这种情况下要用的是 expires 和 Cache-Control 头,而不是 proxy_cache。
你现在加了 expires 30d 和 add_header Cache-Control "public",这部分是对的,但为什么看不到头信息?可能是被其他配置覆盖了,或者 MIME 类型没匹配上。
先用 curl -I 访问那个 .css 文件,确认下实际返回的响应头:
看看有没有 expires 和 cache-control。如果没有,说明 location 没命中。
问题可能出在正则:你写的是
.(css|js)$,少了个反斜杠转义。应该是.(css|js)$,否则会被当作“任意字符+css”来匹配,结果就是没匹配上。改一下配置:
如果你这些静态文件确实是 Nginx 直接返回的(不是通过 proxy_pass 到后端取的),那就删掉 proxy_cache 那行,它在这里没用,反而容易误导。
最后确保 /var/cache/nginx 目录存在且 Nginx worker 进程有读写权限,虽然这不影响静态文件缓存(因为你没真用到 proxy_cache),但如果将来要缓存代理内容,权限必须对。
总结:两个关键点,一是正则写错了导致 location 没生效,二是误用了 proxy_cache。静态资源缓存靠 expires 和 Cache-Control 就够了,不需要 proxy_cache。