如何为返回404状态码的静态文件添加Cache-Control HTTP头部?
解决Nginx为不存在的静态文件添加Cache-Control头部的问题
这个问题我之前排查过,本质是Nginx的location匹配逻辑在搞事情——你写的location ~* \.(js)$只有当请求的JS文件实际存在于服务器上时才会生效。当文件不存在触发404时,请求根本没走到这个location块里,自然不会带上你设置的expires对应的Cache-Control头部。
下面给你两种精准的解决思路:
方法一:针对JS后缀请求,强制统一处理(无论文件是否存在)
通过try_files指令让所有JS请求先尝试找文件,找不到就跳转到指定的命名location处理,确保Cache-Control头部始终被添加:
server { listen *:80; server_name local.test.com; root /var/www/test; # 注意你之前写的是/vat,应该是笔误,改成/var location ~* \.(js)$ { # 先尝试访问请求的文件,不存在则跳转到@js_cache try_files $uri @js_cache; # 存在的文件会直接走这里的expires设置,和你原来的逻辑一致 expires 4s; } # 专门处理不存在的JS文件的命名location location @js_cache { expires 4s; return 404; } }
方法二:全局捕获404错误并添加缓存头部(适合需要给所有404请求加缓存的场景)
如果你的需求是给所有404请求都加上Cache-Control头部,可以用error_page指令统一处理:
server { listen *:80; server_name local.test.com; root /var/www/test; location ~* \.(js)$ { expires 4s; } # 将404错误转发到@handle_404 location处理 error_page 404 = @handle_404; location @handle_404 { expires 4s; return 404; } }
验证效果
修改配置后重新加载Nginx:
nginx -s reload
然后测试不存在的JS文件:
curl -s -I http://local.test.com/fake.js | grep Cache-Control
此时应该能看到预期的输出:
Cache-Control: max-age=4
内容的提问来源于stack exchange,提问作者user2478384
相关产品推荐
相关产品推荐

