浏览器缓存

浏览器缓存

  • 强缓存

    下面两者都表示资源在客户端缓存的有效期

    • Expires

      // 绝对时间,由服务器返回,GMK格式
      浏览器第一次跟服务器请求一个资源,服务器在返回这个资源的同时,在respone的header加上Expires的header
      浏览器在接收到这个资源后,会把这个资源连同所有response header一起缓存下来(所以缓存命中的请求返回的header并不是来自服务器,而是来自之前缓存的header);
      浏览器再请求这个资源时,先从缓存中寻找,找到这个资源后,拿出它的Expires跟当前的请求时间比较,如果请求时间在Expires指定的时间之前,就能命中缓存,否则就不行。
      如果缓存没有命中,浏览器直接从服务器加载资源时,Expires Header在重新加载的时候会被更新。
      
    • Cache-Control

      // 相对时间
      浏览器第一次跟服务器请求一个资源,服务器在返回这个资源的同时,在respone的header加上Cache-Control的header
      浏览器在接收到这个资源后,会把这个资源连同所有response header一起缓存下来;
      浏览器再请求这个资源时,先从缓存中寻找,找到这个资源后,根据它第一次的请求时间和Cache-Control设定的有效期,计算出一个资源过期时间,再拿这个过期时间跟当前的请求时间比较,如果请求时间在过期时间之前,就能命中缓存,否则就不行。
      如果缓存没有命中,浏览器直接从服务器加载资源时,Cache-Control Header在重新加载的时候会被更新。
      

      可同时存在, cache-control 优先级高于expires

  • 协商缓存

    • 当浏览器对某个资源的请求没有命中强缓存,就会发一个请求到服务器,验证协商缓存是否命中,如果协商缓存命中,请求响应返回的http状态为304并且会显示一个Not Modified的字符串

    • 协商缓存是利用的是【Last-Modified,If-Modified-Since】【ETag、If-None-Match】这两对Header来管理的。

    • 【Last-Modified,If-Modified-Since】的控制缓存的原理是:

    1.浏览器第一次跟服务器请求一个资源,服务器在返回这个资源的同时,在respone的header加上Last-Modified的header,这个header表示这个资源在服务器上的最后修改时间
    
    2.浏览器再次跟服务器请求这个资源时,在request的header上加上If-Modified-Since的header,这个header的值就是上一次请求时返回的Last-Modified的值
    
    3.服务器再次收到资源请求时,根据浏览器传过来If-Modified-Since和资源在服务器上的最后修改时间判断资源是否有变化,如果没有变化则返回304 Not Modified,但是不会返回资源内容;如果有变化,就正常返回资源内容。当服务器返回304 Not Modified的响应时,response header中不会再添加Last-Modified的header,因为既然资源没有变化,那么Last-Modified也就不会改变,这是服务器返回304时的response header
    
    4.浏览器收到304的响应后,就会从缓存中加载资源。
    
    5.如果协商缓存没有命中,浏览器直接从服务器加载资源时,Last-Modified Header在重新加载的时候会被更新,下次请求时,If-Modified-Since会启用上次返回的Last-Modified值。
    
    • 【ETag、If-None-Match】【Last-Modified,If-Modified-Since】都是根据服务器时间返回的header,一般来说,在没有调整服务器时间和篡改客户端缓存的情况下,这两个header配合起来管理协商缓存是非常可靠的,但是有时候也会服务器上资源其实有变化,但是最后修改时间却没有变化的情况,而这种问题又很不容易被定位出来,而当这种情况出现的时候,就会影响协商缓存的可靠性。所以就有了另外一对header来管理协商缓存,这对header就是【ETag、If-None-Match】。它们的缓存管理的方式是:

    • 1.浏览器第一次跟服务器请求一个资源,服务器在返回这个资源的同时,在respone的header加上ETag的header,这个header是服务器根据当前请求的资源生成的一个唯一标识,这个唯一标识是一个字符串,只要资源有变化这个串就不同,跟最后修改时间没有关系,所以能很好的补充Last-Modified的问题
      
      2.浏览器再次跟服务器请求这个资源时,在request的header上加上If-None-Match的header,这个header的值就是上一次请求时返回的ETag的值
      
      3.服务器再次收到资源请求时,根据浏览器传过来If-None-Match和然后再根据资源生成一个新的ETag,如果这两个值相同就说明资源没有变化,否则就是有变化;如果没有变化则返回304 Not Modified,但是不会返回资源内容;如果有变化,就正常返回资源内容。与Last-Modified不一样的是,当服务器返回304 Not Modified的响应时,由于ETag重新生成过,response header中还会把这个ETag返回,即使这个ETag跟之前的没有变化
      
      4.浏览器收到304的响应后,就会从缓存中加载资源。
      

浏览器行为对缓存的影响

  • 如果资源已经被浏览器缓存下来,在缓存失效之前,再次请求时,默认会先检查是否命中强缓存,如果强缓存命中则直接读取缓存,如果强缓存没有命中则发请求到服务器检查是否命中协商缓存,如果协商缓存命中,则告诉浏览器还是可以从缓存读取,否则才从服务器返回最新的资源。这是默认的处理方式

  • 以下行为可能改变缓存的默认处理方式

    • 当ctrl+f5强制刷新网页时,直接从服务器加载,跳过强缓存和协商缓存;

    • 当f5刷新网页时,跳过强缓存,但是会检查协商缓存;

posted @ 2020-04-03 11:44  huangbohang  阅读(121)  评论(0编辑  收藏  举报