1. 前言
前序项目中遇到过,前端文件已更新,但是用户依然看到旧版页面的情况。
近日看到《三步根治前端缓存 “顽疾”》一文,此处做摘录备份。
2. 现象及解决思路
2.1 现象
• 用户反馈页面功能异常,但开发者本地测试正常
• 浏览器反复刷新后,index.html
引用的仍是旧版 JS/CSS 文件
• 查看网络请求,某些文件状态码显示 304 Not Modified
或 200 OK (from memory cache)
2.2 解决思路
• HTML 文件:禁止缓存,永远从服务器获取最新版本
• 静态资源(JS/CSS/ 图片):带 hash
文件名 + 长期缓存
• 静态资源(JS/CSS/ 图片):非 hash
文件名 + 短期缓存
3. Nginx/Openresty反代配置
server {
listen 80;
server_name your-domain.com;
root /path/to/your/dist;
# ==============================================
# 1. 处理 /assets/ 目录下的带哈希资源(长期强缓存)
# ==============================================
location ^~ /assets/ {
# 缓存 1 年(兼容旧浏览器)
expires 1y;
# 现代浏览器强缓存(immutable 表示内容不可变)
add_header Cache-Control "public, max-age=31536000, immutable";
# 安全加固,防止 MIME 类型嗅探
add_header X-Content-Type-Options "nosniff";
# 直接返回文件,不再检查其他规则
try_files $uri =404;
}
# ==============================================
# 2. 处理其他目录下的无哈希静态资源(短期缓存)
# ==============================================
location ~* \.(?:js|mjs|css|png|jpg|jpeg|gif|ico|svg|webp|avif|woff|woff2|ttf|otf|eot|mp4|mp3|webm|ogg|json|xml|txt|csv|wasm)$ {
# 排除 /assets/ 目录的干扰
if ($request_uri ~* "^/assets/") {
break; # 跳过此规则
}
# 不包含哈希值的静态资源,设置较短的缓存时间
add_header Cache-Control "public, max-age=3600, must-revalidate";
# 安全加固,防止 MIME 类型嗅探
add_header X-Content-Type-Options "nosniff";
# 直接返回文件,不再检查其他规则
try_files $uri =404;
}
# ==============================================
# 3. 处理前端路由请求(禁用缓存)
# ==============================================
location / {
# 禁用缓存
add_header Cache-Control "no-store, no-cache, must-revalidate";
add_header Pragma no-cache;
add_header Expires 0;
# 先尝试匹配静态资源,否则回退到 index.html
try_files $uri $uri/ @fallback;
}
# ==============================================
# 4. 统一回退到 index.html
# ==============================================
location @fallback {
rewrite ^ /index.html last;
}
}
关键解释:
• immutable:告诉浏览器 “此文件永不变”,跳过协商缓存
• no-store:对 HTML 文件下达 “禁用缓存” 绝杀令
• must-revalidate:资源过期时,在向原始服务器验证之前,缓存不能用该资源响应后续请求
• Pragma no-cache:禁用缓存