HTTP缓存策略到底该怎么配才有效?

书生シ米阳 阅读 55

我给静态资源加了 Cache-Control: max-age=31536000,但每次刷新页面还是会重新请求,浏览器根本不走缓存,这是为啥?

我试过在 Nginx 里这样配置:

location ~* .(js|css|png|jpg|jpeg|gif|ico|woff2)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
}

但开发者工具里看到的响应头却是 Cache-Control: no-cache,好像被别的地方覆盖了?是不是还要改 HTML 里的引用方式?

我来解答 赞 12 收藏
二维码
手机扫码查看
2 条解答
码农爱香
这问题我可太熟了,当时我也卡在这好久。首先你 Nginx 配置看起来是对的,但要注意优先级问题。

你的 Cache-Control 被覆盖成 no-cache,很可能是因为服务器端代码或框架默认设置在捣乱。比如说某些框架会在响应头里自动加上缓存控制,这种情况下 Nginx 的配置会被覆盖掉。

建议先检查后端代码,看看有没有类似 header('Cache-Control: no-cache') 这样的调用。如果有,把它去掉或者调整优先级。

另外记得清理浏览器缓存再测试,有时候旧的缓存设置会影响测试结果。我以前就因为这个浪费了不少时间。

如果确定后端没问题,可以试试把 add_header 改成这样:
add_header Cache-Control "public, immutable" always;

加上 always 参数能保证这个头一定会被设置,避免被其他地方覆盖。

最后说一句,immutable 确实能提升静态资源缓存命中率,但要注意兼容性问题,不是所有浏览器都支持。我当时为了兼容老旧IE可是折腾了一阵子。
点赞
2026-03-29 16:08
打工人路阳
当时我也卡在这,差点怀疑自己是不是得了老年痴呆。后来发现,可能是其他配置覆盖了你的设置。你可以在 Nginx 的配置文件里搜索一下有没有其他的 Cache-Control 头被设置了。有时候全局配置或者 location 块里的其他配置会不小心覆盖掉特定 location 的设置。

你可以尝试在你的 location 块里加上这一行,确保你的设置不会被覆盖:
add_header Cache-Control "public, immutable" always;

这个 always 参数会强制覆盖之前的任何 Cache-Control 设置。

另外,检查一下你的 HTML 文件,确保静态资源的链接没有加一些特殊的参数,比如时间戳或者版本号,这些都会导致浏览器认为资源是新的,从而不走缓存。

如果这些都没有问题,可以试试清除浏览器缓存,有时候浏览器自己也会搞些奇怪的事儿。希望这能帮到你,别再熬夜了。
点赞
2026-03-23 04:00