首页 > 技术文章 > Http缓存

terrymin 2020-09-23 13:50 原文

 一 缓存分类:

 二 浏览器缓存策略强缓存与协商缓存

HTTP缓存一般是针对Get请求做缓存,Post很少有缓存。从第二次请求开始,浏览器每次发起请求时,先在本地缓存中查找结果以及缓存标识,然后根据缓存标识来判断是否使用本地缓存。如果缓存有效,则使用本地缓存;否则,则向服务器发起请求并携带缓存标识。缓存过程划分为两个部分(根据是否需向服务器发起HTTP请求):强制缓存和协商缓存,强缓优先于协商缓存。缓存运行整体流程:

    1 强缓存,服务器通知浏览器一个缓存时间,在缓存时间内,下次请求,直接读取浏览器本地资源,在network中显示的是from memory或者from disk;不在时间内,执行比较缓存策略。

      控制强制缓存的字段有:Expires(http1.0)和Cache-Control(http1.1):

         1.1Cache-control是一个相对时间,用以表达自上次请求正确的资源之后的多少秒的时间段内缓存有效。Cache-control 常用值:

    • max-age:即最大有效时间。
    • must-revalidate:如果超过了 max-age 的时间,浏览器必须向服务器发送请求,验证资源是否还有效。
    • no-cache:不使用强缓存,需要与服务器验证缓存是否新鲜(协商缓存)。
    • no-store: 不使用缓存,包括强缓存与协商缓存。
    • public:所有的内容都可以被缓存 (包括客户端和代理服务器, 如 CDN)
    • private:所有的内容只有客户端才可以缓存,代理服务器不能缓存。默认值。

         1.2Expires是一个绝对时间(当前时间+缓存时间)。用以表达在这个时间点之前发起请求可以直接从浏览器中读取数据,而无需发起请求。

         1.3两者比较:Cache-Control的优先级比Expires的优先级高。前者的出现是为了解决Expires在浏览器时间被手动更改导致缓存判断错误的问题。如果同时存在则使用Cache-control。

         1.4强缓存设置:强缓存设置靠请求头的Cache-Control或者Expires;Cache-Control设置的是个相对于现在的时间,单位是秒,Expires设置的是GMT时间,以设置10秒为例:

1 res.setHeader('Expires',new Date(Date.now()+10*1000).toGMTString())
2     res.setHeader('Cache-Control','max-age=10')

 

     2 协商缓存,让客户端与服务器之间能实现缓存文件是否更新的验证、提升缓存的复用率,将缓存信息中的Etag和Last-Modified通过请求发送给服务器,由服务器校验,返回304状态码时,浏览器直接使用缓存。

     协商缓存有 2 组字段(不是两个),控制协商缓存的字段有:Last-Modified/If-Modified-since(http1.0)和Etag/If-None-match(http1.1)

          2.1 Last-Modified/If-Modified-since表示的是服务器的资源最后一次修改的时间;

    • 优势特点
      • 1、不存在版本问题,每次请求都会去服务器进行校验。服务器对比最后修改时间如果相同则返回304,不同返回200以及资源内容。
    • 劣势问题
      • 2、只要资源修改,无论内容是否发生实质性的变化,都会将该资源返回客户端。例如周期性重写,这种情况下该资源包含的数据实际上一样的。
      • 3、以时刻作为标识,无法识别一秒内进行多次修改的情况。 如果资源更新的速度是秒以下单位,那么该缓存是不能被使用的,因为它的时间单位最低是秒。
      • 4、某些服务器不能精确的得到文件的最后修改时间。
      • 5、如果文件是通过服务器动态生成的,那么该方法的更新时间永远是生成的时间,尽管文件可能没有变化,所以起不到缓存的作用。

          2.2 Etag/If-None-match表示的是服务器资源的唯一标识,只要资源变化,Etag就会重新生成。

    • 优势特点
      • 1、可以更加精确的判断资源是否被修改,可以识别一秒内多次修改的情况。
      • 2、不存在版本问题,每次请求都会去服务器进行校验。
    • 劣势问题
      • 1、计算ETag值需要性能损耗。
      • 2、分布式服务器存储的情况下,计算ETag的算法如果不一样,会导致浏览器从一台服务器上获得页面内容后到另外一台服务器上进行验证时现ETag不匹配的情况。

          2.3 Etag/If-None-match的优先级比Last-Modified/If-Modified-since高。if-Modified-since与if-None-match都是用于客户端的请求头中。

 

三 强缓存:浏览器不会向服务器发送任何请求,直接从本地缓存中读取文件并返回Status Code: 200 OK

  1. 200 form memory cache : 不访问服务器,一般已经加载过该资源且缓存在了内存当中,直接从内存中读取缓存。浏览器关闭后,数据将不存在(资源被释放掉了),再次打开相同的页面时,不会出现from memory cache。
  2. 200 from disk cache: 不访问服务器,已经在之前的某个时间加载过该资源,直接从硬盘中读取缓存,关闭浏览器后,数据依然存在,此资源不会随着该页面的关闭而释放掉下次打开仍然会是from disk cache。
  3. 优先访问memory cache,其次是disk cache,最后是请求网络资源。

四 协商缓存: 向服务器发送请求,服务器会根据这个请求的request header的一些参数来判断是否命中协商缓存,如果命中,则返回304状态码并带上新的response header通知浏览器从缓存中读取资源;

 

参考链接:

HTTP缓存策略与区别:https://github.com/lgwebdream/FE-Interview/issues/14

从优化角度看缓存:https://github.com/amandakelake/blog/issues/43

缓存设置:https://juejin.cn/post/6942264171870289956

大公司里怎样开发和部署前端代码? - 张云龙的回答 - 知乎 https://www.zhihu.com/question/20790576/answer/32602154  

 

 

 

推荐阅读