2团
Published on 2025-07-07 / 0 Visits
0
0

​​Nginx/Openresty配置:根治前端缓存导致的“页面不更新”

1. 前言

前序项目中遇到过,前端文件已更新,但是用户依然看到旧版页面的情况。

近日看到三步根治前端缓存 “顽疾”一文,此处做摘录备份。

2. 现象及解决思路

2.1 现象

用户反馈页面功能异常,但开发者本地测试正常

浏览器反复刷新后,index.html 引用的仍是旧版 JS/CSS 文件

查看网络请求,某些文件状态码显示 304 Not Modified200 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:禁用缓存


Comment