Vue SPA 项目,浏览器和 nginx 反向代理缓存问题解决实方案

栏目: JavaScript · 发布时间: 5年前

  1. 问题背景
    a. 浏览器端在每次发布新的版本时候,总会出现因为SPA项目中index.html文件 (200 ok from disk cache 不发送请求,直接取用了本地磁盘缓存) 和服务端版本不一致的问题,导致用户不能及时更新,需要通过手动刷新来强制从服务端更新文件。
    Vue SPA 项目,浏览器和 nginx 反向代理缓存问题解决实方案 b. 补充一下,服务端和浏览器之间架构。

    Vue SPA 项目,浏览器和 nginx 反向代理缓存问题解决实方案

  2. 三级缓存问题

    上述,我们看到浏览器没有发出请求直接从磁盘中取出index.html文件,这其实是二级缓存。 

    当浏览器访问的服务器没有设置缓存时,浏览器先200 OK from memory cache,如果浏览器缓存中没有该文件,那么浏览器会200 OK from disk cache 从磁盘中找改文件,如果还找不到,浏览器会从服务端请求该文件下载使用。

    Vue SPA 项目,浏览器和 nginx 反向代理缓存问题解决实方案 b. 浏览器第二次请求上次请求过的url时,浏览器会在HTTP请求头添加一个If-Modified-Since的标记,用来询问服务器该时间之后文件是否被修改过。 Vue SPA 项目,浏览器和 nginx 反向代理缓存问题解决实方案
  3. Last-Modified/If-Modified-Since

    a. 当浏览器第一次请求一个url时,服务器端的返回状态码为200,同时HTTP响应头会有一个Last-Modified标记着文件在服务器端最后被修改的时间。

  4. Etag/If-None-Match
    a. 当浏览器第一次请求一个url时,服务器端的返回状态码为200,同时HTTP响应头会有一个Etag,存放着服务器端生成的一个序列值。
    Vue SPA 项目,浏览器和 nginx 反向代理缓存问题解决实方案 b. 浏览器第二次请求上一次请求过的url时,当浏览器第一次请求一个url时,服务器端的返回状态码为200,同时HTTP响应头会有一个Last-Modified标记着文件在服务器端最后被修改的时间。
    Vue SPA 项目,浏览器和 nginx 反向代理缓存问题解决实方案
  5. Etag 主要为了解决 Last-Modified 无法解决的一些问题:


    a. Etag和Last-Modified特点:
    1).它们都属于协商缓存,对内容的有效性进行验证。
    2).Etag的值通常为文件内容的哈希值;而Last-Modified为最后修改的时间。
    3).Last-Modified只能精确到秒,秒之内的内容更新Etag才能检测。
    4).文件有时会定时重新生成相同内容,Last-Modified不能很好辨别,某些服务器甚至不能精确的得到文件的最后修改时间。
    5).Etag每次服务端生成都需要进行读写操作,而Last-Modified只需要读取操作,Etag的消耗是更大的。
    Etag更像是Last-Modified的一种补充、完善。
  6. Expires

    Expires是RFC 2616(HTTP/1.0)协议中和网页缓存相关字段。用来控制缓存的失效日期,要注意的是,HTTP/1.0有一个功能比较弱的缓存控制机制:Pragma,使用HTTP/1.0的缓存将忽略Expires和Cache-Control头。
    可以在nginx中设置 expires:-1; 如下
    Vue SPA 项目,浏览器和 nginx 反向代理缓存问题解决实方案 其它配置:
    location ~ \.(wma|wmv|asf|mp3|mmf|zip|rar|swf|flv)$ {
                   root /var/www/upload/;
                   expires max;
           }复制代码
    expires 指令可以控制 HTTP 应答中的“ Expires ”和“ Cache-Control ”的头标(起到控制页面缓存的作用)
    语法:expires [time|epoch|max|pff]
    默认值:off
    expires指令控制HTTP应答中的“Expires”和“Cache-Control”Header头部信息,启动控制页面缓存的作用
    time:可以使用正数或负数。“Expires”头标的值将通过当前系统时间加上设定time值来设定。
    time值还控制"Cache-Control"的值:
    负数表示no-cache
    正数或零表示max-age=time
    
    epoch:指定“Expires”的值为 1 January,1970,00:00:01 GMT
    max:指定“Expires”的值为31 December2037 23:59:59GMT,"Cache-Control"的值为10年。
    -1:指定“Expires”的值为当前服务器时间-1s,即永远过期。
    off:不修改“Expires”和"Cache-Control"的值
    
    expires使用了特定的时间,并且要求服务器和客户端的是中严格同步。
    而Cache-Control是用max-age指令指定组件被缓存多久。
    对于不支持http1.1的浏览器,还是需要expires来控制。所以最好能指定两个响应头。
    但HTTP规范规定max-age指令将重写expires头。复制代码
  7. 在设置Expires、Etag/If-None-Match、Last-Modified/If-Modified-Since缓存机制下,浏览器第一次请求和第二次请求缓存机制

    a.第一次请求
    Vue SPA 项目,浏览器和 nginx 反向代理缓存问题解决实方案

    b.第二次请求

    Vue SPA 项目,浏览器和 nginx 反向代理缓存问题解决实方案
  8. 用户操作与缓存
    Vue SPA 项目,浏览器和 nginx 反向代理缓存问题解决实方案
  9. 基于vue-cli3.x脚手架下打包的spa项目缓存机制方案

    a.思路
    spa项目的网站域名映射的ip地址下入口文件是index.html,除此之外,js、css、img、font等等静态文件都是从index.html下加载出来的。
    在vue-cli3.x脚手架打包下的js、css、img、font等静态文件名都是包含hash,所以每次打包index.html加载出来的文件都不会出现相同名称文件,因此也不会出现缓存问题。
    因此,我们只需要通过配置nginx,设置协商缓存机制,每次发版本后,让浏览器每次使用的index.html,这样js、css、img、font等静态文件都是最新。
    本质上,我只需要设置index.html受nginx配置的缓存机制的影响就好了,js、css、img、font等静态文件可以留给浏览器自身的缓存机制来控制,当不是第一次请求js、css、img、font等静态文件时,这些资源文件可以 from disk cache/from memory cache ,直接从缓存中取对应的文件,这样大大减少服务器的资源消耗,同时,通过网友文件的加载速度和页面渲染速度。
    b.遇到的问题
    在nginx配置过程,我们尝试取捕捉index.html文件,捕捉到之后设置如下:
    location ^~ /aa/ {  
            proxy_set_header  X-Real-IP  $remote_addr;
            #html 文件不缓存(你也可以设置为协商缓存,但是参考其他大厂方案,一般index.html入口文件都不作缓存,一方面是因为index.html很小基本在1KB左右,另外这个文件内容变化频繁)
            if ($request_filename ~* ^.*?.(html|htm)$){
                expires -1s;
                add_header Cache-Control no-cache;
               }
             proxy_pass  http://XXX/aa/;               
          } 复制代码
    但是这样是捕捉不到index.html的,无法控制index.html的缓存。
    原因分析,是因为我们在捕捉过程没有一个文件路径是含有 .html 后缀名的,因此无法过滤出index.html加以设置。
    c.解决方案
    我们无法通过捕捉含有 .html 后面的路径,但是我们知道“/aa/”所对应的文件就是index.html,所以我们来捕捉这个“/aa/”路径,且不捕捉该路径下子级文件(这样把子文件夹中的js、css、img、font等静态文件也设置来),配置如下:
    location ^~ /aa/ {  
       proxy_set_header  X-Real-IP  $remote_addr;        #html 文件不缓存(你也可以设置为协商缓存,但是参考其他大厂方案,一般index.html入口文件都不作缓存,一方面是因为index.html很小基本在1KB左右,另外这个文件内容变化频繁)
            if ( $request_uri = "/aa/") {
                expires -1s;
                add_header Cache-Control no-cache;
           #add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";           }
             proxy_pass  http://XXX/aa/;           
          } 复制代码
    如此,我们就能简单的过滤出index.html,并加以设置缓存。
    设置完成后浏览器第一次加载:
    Vue SPA 项目,浏览器和 nginx 反向代理缓存问题解决实方案
    设置完成后浏览器第二次加载:
    Vue SPA 项目,浏览器和 nginx 反向代理缓存问题解决实方案
    通过以上设置,我们可以很轻松的解决了浏览器和服务器之间的缓存问题。
    有建议或问题可以加群qq交流 535798405

以上所述就是小编给大家介绍的《Vue SPA 项目,浏览器和 nginx 反向代理缓存问题解决实方案》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

软利器

软利器

保罗·莱文森 / 何道宽 / 复旦大学出版社 / 2011-5 / 35.00元

《软利器:信息革命的自然历史与未来》内容简介:何谓“软利器”?一种轻盈、透明、无质无形、难以把握的力量,由信息和物理载体构成,这就是媒介。了解媒介的属性和演化规律的人,常占尽优势:反之则身处险境。是不是有些危言耸听? 如果你看过保罗•莱文森的这本《软利器:信息革命的自然历史与未来》,或许就会深信不疑。在书中,莱文森如同一位经验丰富的航海家,带领你穿越媒介时空——你将邂逅古埃及的法老、古希腊的......一起来看看 《软利器》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具