Nginx设置缓存有效期,静态文件缓存策略
想让网站加载更快,合理设置 Nginx 静态文件缓存有效期是最直接有效的方法之一。
本文会带你从零开始,学会用 expires 指令控制图片、CSS、JS 等文件的浏览器缓存时间,并给出不同场景下的策略建议,最后验证配置是否生效。
为什么需要设置缓存有效期
浏览器第一次访问网站时,会下载图片、样式表、脚本等静态文件。
如果服务器不告诉浏览器这些文件可以缓存多久,下次访问时浏览器可能重新请求所有文件,导致加载变慢、服务器压力增大。
通过 Nginx 的 expires 指令,可以设置一个时间,告诉浏览器在这段时间内直接使用本地缓存,不再向服务器发请求。
这样既能加快用户访问速度,也能减少服务器带宽消耗。
一个可独立摘录的结论: 为静态文件设置较长的缓存有效期(如 30 天),能显著减少重复请求,但需要配合文件指纹或版本号来避免更新后用户仍用旧缓存。
找到并编辑 Nginx 配置文件
通常 Nginx 的主配置文件位于 /etc/nginx/nginx.conf,
站点配置在 /etc/nginx/conf.d/ 或 /etc/nginx/sites-available/ 目录下(不同系统可能不同,
可用 nginx -t 查看实际加载的配置文件)。
假设你的网站配置在 /etc/nginx/conf.d/example.conf,用编辑器打开它:
sudo vim /etc/nginx/conf.d/example.conf
如果你使用宝塔面板,可以在“网站” → 对应站点 → “配置文件”中直接编辑。
使用 expires 指令设置缓存时间
在 server 块或 location 块中添加 expires 指令。
基本语法:
expires 30d;
表示缓存 30 天。
也可以使用 h(小时)、m(分钟)。
例如,针对图片文件设置 7 天缓存:
location ~* \.(jpg|jpeg|png|gif|ico|webp)$ {
expires 7d;
add_header Cache-Control "public";
}
对于 CSS 和 JS 文件,可以设置更长时间,但建议结合版本号或哈希值:
location ~* \.(css|js)$ {
expires 30d;
add_header Cache-Control "public";
}
如果不希望某些文件被缓存,可以设置 expires -1; 或 expires off;。
重要: expires 指令会自动添加 Expires 和 Cache-Control 响应头,无需手动添加。
针对不同文件类型制定缓存策略
静态文件类型多样,缓存时间应有所区别。
以下是一个参考策略,你可以根据实际情况调整:
- 图片、字体文件:变化频率低,可设置 30 天或更长。
- CSS、JavaScript:建议设置 7 到 30 天,但务必使用文件名哈希或查询参数版本号,例如
style.a1b2c3.css,这样更新文件后链接改变,浏览器会重新下载。 - HTML 文件:通常不缓存或设置很短时间(如 1 小时),避免用户看到旧页面。
- 视频、音频:可设置较长时间,但注意服务器磁盘空间。
配置示例:
# 图片和字体
location ~* \.(jpg|jpeg|png|gif|ico|webp|svg|woff2?|ttf|eot)$ {
expires 30d;
add_header Cache-Control "public";
}
# CSS 和 JS
location ~* \.(css|js)$ {
expires 7d;
add_header Cache-Control "public";
}
# HTML 不缓存
location ~* \.(html|htm)$ {
expires -1;
add_header Cache-Control "no-cache";
}
避坑指南:常见错误与注意事项
- 缓存时间过长导致更新不生效:如果用户浏览器缓存了旧版 CSS,即使你更新了文件,用户仍看到旧样式。解决方案是给文件名添加哈希值或版本号,或者设置较短的缓存时间。
- 忘记添加 Cache-Control:
expires会自动添加Cache-Control,但如果你手动设置了add_header Cache-Control,可能会覆盖,建议统一用expires。 - 权限问题:修改配置文件后需要重新加载 Nginx,如果报错
nginx: [emerg] unknown directive,检查指令拼写和上下文。 - CDN 缓存:如果使用了 CDN,CDN 可能忽略源站的缓存头,需要单独在 CDN 控制台设置缓存规则。
- 动态文件误缓存:确保
location匹配规则不会误伤动态请求,例如 PHP 文件。
一个可独立摘录的判断条件: 如果你无法修改静态文件名(如没有构建工具),
建议将 CSS/JS 缓存时间设为 1 天以内,
并依赖 ETag 或 Last-Modified 做协商缓存。
测试配置并重载 Nginx
保存配置文件后,先测试语法:
sudo nginx -t
如果显示 syntax is ok 和 test is successful,则重载 Nginx:
sudo systemctl reload nginx
或使用宝塔面板的重载按钮。
验证缓存是否生效
用 curl 查看响应头:
curl -I https://你的域名/图片.jpg
在输出中查找 Expires 和 Cache-Control 字段,
如果看到类似 Cache-Control: 和
max-age=2592000Expires: 就表示配置成功。
...
也可以打开浏览器开发者工具,在 Network 面板中查看静态文件的响应头,确认 Cache-Control 的值。
一个可独立摘录的操作结果: 如果 Cache-Control 显示 max-age=2592000,说明该文件被缓存了 30 天,浏览器在有效期内不会重复请求。
常见疑问
问:设置 expires 后,用户强制刷新会重新下载吗?
会。用户按 Ctrl+F5 强制刷新时,浏览器会忽略缓存,重新请求所有资源。
问:为什么我设置了 expires,但响应头里没有 Cache-Control?
可能是其他配置覆盖了,检查是否有 add_header 重复设置,或者 expires 被放在了错误的块中。
问:动态生成的图片能缓存吗?
可以,但需要确保 URL 包含唯一标识(如时间戳或哈希),否则可能缓存错误内容。
问:Nginx 的 expires 和 proxy_cache 有什么区别?
expires 控制浏览器缓存,proxy_cache 控制 Nginx 作为反向代理时对后端响应的缓存,两者作用层级不同。
最后
正确设置 Nginx 静态文件缓存有效期,能明显提升网站性能。
建议先从图片和字体开始,逐步调整 CSS/JS 和 HTML。
每次修改后都用 curl 或浏览器验证响应头,确保策略符合预期。
如果遇到缓存不更新问题,优先检查文件名是否带版本号。