在 Nginx 中为 Django 静态文件设置缓存,最稳妥的做法是在 location 块中针对静态资源路径配置 expires 指令,通常设为 30 天或更长,但前提是静态文件名已包含版本哈希。
先说结论:配置 expires 能显著减少重复请求,但配错会导致用户一直访问旧文件。
- 适合:静态资源与动态请求分离的部署架构
- 先准备:确保 Django 已运行 collectstatic 且文件名带哈希
- 验收:通过 curl 检查响应头中的 Cache-Control 字段
配置前提
在配置 Nginx 之前,需确保 Django 项目已正确收集静态文件。假设 Django 的 STATIC_ROOT 设置为 /var/www/static,且 Nginx 需映射 /static/ URL 到此目录。
python manage.py collectstatic执行后,确认 /var/www/static 目录下存在 css、js 等资源文件,且文件名最好包含哈希值(如 style.a1b2c3.css)。
Nginx 配置详解
在 server 块中找到或新增针对静态目录的 location 配置。以下是完整的配置上下文示例:
server {
listen 80;
server_name your-domain.com;
location /static/ {
# 方式一:使用 alias(推荐,路径映射更直观)
alias /var/www/static/;
expires 30d;
access_log off;
}
# 方式二:使用 root(注意路径拼接规则)
# location /static/ {
# root /var/www;
# expires 30d;
# access_log off;
# }
}root 与 alias 路径映射区别:
- alias:直接替换 location 路径。location /static/ 匹配后,直接指向 alias 指定的目录。注意 alias 路径末尾建议保留斜杠,与 location 对应。
- root:会将 location 路径拼接到 root 路径后。若配置 root /var/www; 且 location /static/,实际路径为 /var/www/static/。若配置 root /var/www/static;,实际路径会变成 /var/www/static/static/,导致 404。
注意:expires 指令会自动生成 Cache-Control 和 Expires 头,通常无需额外添加 add_header Cache-Control,避免产生重复头部或冲突。
效果验证方法
使用 curl 命令查看响应头,确认 Cache-Control 和 Expires 字段是否存在且符合预期。
curl -I https://你的域名.com/static/images/logo.png # 请替换为实际域名期望看到类似以下输出:
Cache-Control: max-age=2592000
Expires: Thu, 31 Dec 2037 23:55:55 GMT如果看到 Cache-Control: no-cache 或缺失相关字段,说明配置未生效或 location 匹配错误。配置修改后需执行以下命令重载:
nginx -t && systemctl reload nginx常见故障与排查
1. 文件名无哈希却设了长缓存
如果静态文件名不带版本哈希(如 style.css),设置 expires 30d 后,更新文件内容会导致用户端一直缓存旧版本。这种情况下应设置 expires 1h 或使用 no-cache。
2. location 匹配优先级问题
Nginx 的 location 匹配有优先级,确保静态文件的 location 没有被其他正则规则意外覆盖。可以使用精确匹配或前缀匹配优先。
3. MIME 类型缺失
确保 Nginx 配置中包含了 mime.types,否则某些文件可能无法被浏览器正确识别和缓存,通常默认配置已包含,自定义配置时需检查 include 语句。
4. 动态生成的静态文件
部分 Django 项目会在运行时生成静态文件,这类文件不适合长缓存,需单独区分路径配置。