Nginx配置了缓存但静态文件没生效怎么办?

一俊郝 阅读 77

折腾了一下午配置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?

我来解答 赞 9 收藏
二维码
手机扫码查看
2 条解答
シ文亭
シ文亭 Lv1
你的配置有几个关键问题,我来挨个分析下。首先你没用 proxy_pass 却用了 proxy_cache,这就像买了锅但没开火一样尴尬。

问题核心在于:
1. 这是静态文件不是反向代理,应该用 fastcgi_cache 或者直接 expires 指令
2. 缓存目录权限确实要检查,建议755
3. 你漏了关键的缓存验证头

正确的配置应该是这样:

server {
# 静态文件处理直接走try_files
location ~* .(css|js)$ {
try_files $uri =404;
expires 30d;
add_header Cache-Control "public";
add_header X-Cache-Status $upstream_cache_status;

# 关键在这!设置缓存key
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_valid 200 30d;
fastcgi_cache_use_stale error timeout updating;
}
}


需要注意:
- 如果你是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 减少日志噪音,反正静态文件访问日志也没啥用。
点赞
2026-03-10 13:05
司空一莹
先检查一下你的 location 块里有没有 proxy_pass 指令。你用了 proxy_cache,但没看到 proxy_pass,这就意味着请求根本没走反向代理流程,缓存自然不会生效。

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 文件,确认下实际返回的响应头:

curl -I http://你的域名/assets/style.css


看看有没有 expires 和 cache-control。如果没有,说明 location 没命中。

问题可能出在正则:你写的是 .(css|js)$,少了个反斜杠转义。应该是 .(css|js)$,否则会被当作“任意字符+css”来匹配,结果就是没匹配上。

改一下配置:

location ~* .(css|js)$ {
expires 30d;
add_header Cache-Control "public";
}


如果你这些静态文件确实是 Nginx 直接返回的(不是通过 proxy_pass 到后端取的),那就删掉 proxy_cache 那行,它在这里没用,反而容易误导。

最后确保 /var/cache/nginx 目录存在且 Nginx worker 进程有读写权限,虽然这不影响静态文件缓存(因为你没真用到 proxy_cache),但如果将来要缓存代理内容,权限必须对。

总结:两个关键点,一是正则写错了导致 location 没生效,二是误用了 proxy_cache。静态资源缓存靠 expires 和 Cache-Control 就够了,不需要 proxy_cache。
点赞 1
2026-02-12 08:00