http强缓存协商缓存

2,612 阅读4分钟

走起,来吧少年

1、什么是缓存

良好的缓存策略可以降低资源的重复加载提高网页的整体加载速度通常浏览器缓存策略分为两种:强缓存和协商缓存
  • 相同点:如果命中,都是从客户端缓存中加载资源,而不是从服务器加载资源数据
  • 不同点:强缓存不发请求到服务器,协商缓存会发请求到服务器

2、基本原理

  • 1).浏览器在加载资源时,根据请求头的expires和cache-control判断是否命中强缓存,是则直接从缓存读取资源,不会发请求到服务器
  • 2)如果没有命中强缓存,浏览器一定会发送一个请求到服务器,通过last-modified和etag验证资源是否命中协商缓存,如果命中,服务器会将这个请求返回,但是不会返回这个资源的数据,依然是从缓存中读取资源
  • 3)如果前面两者都没有命中,直接从服务器加载资源

3、Expires和Cache-Control 强缓存

  • Expires

    它描述的是一个绝对时间,由服务器返回。浏览器进行第一次请求时,服务器会在返回头部加上Expires,下次请求,如果在这个时间之前则命中缓存,

注:Expires 受限于本地时间,如果修改了本地时间,可能会造成缓存失效
  • Cache-Control

    表示的是相对时间,该值是利用max-age判断缓存的生命周期,是以秒为单位,如何在生命周期时间内,则命中缓存,优先级高于 Expires

题外tips,Cache-Control 其他常见值

Cache-Control:no-cache:强制客户端直接向服务器发送请求,也就是说每次请求都必须向服务器发送。服务器接收到  请求,然后判断资源是否变更,是则返回新内容,否则返回304,未变更。这个很容易让人产生误解,使人误以为是响应不被缓存。实际上Cache-Control: no-cache是会被缓存的,只不过每次在向客户端(浏览器)提供响应数据时,缓存都要向服务器评估缓存响应的有效性
Cache-Control: no-store才是真正的不缓存数据到本地
Cache-Control: public可以被所有用户缓存(多用户共享),包括终端和CDN等中间代理服务器
Cache-Control: private只能被终端浏览器缓存(而且是私有缓存),不允许中继缓存服务器进行缓存

3、Last-Modified/If-Modified-Since 和 ETag/If-None-Match 协商缓存

很显然,协商缓存,字面意思就是和服务器协商一下,看是否需要缓存

  • Last-Modified/If-Modified-Since

    Last-Modified 表示本地文件最后修改日期,浏览器会在请求 header加上If-Modified-Since(上次返回的Last-Modified的值),询问服务器在该日期后资源是否有更新,有更新的话就会将新的资源发送回来

  • ETag/If-None-Match

    Etag就像一个指纹,资源变化都会导致ETag变化,跟最后修改时间没有关系,ETag可以保证每一个资源是唯一的 If-None-Match的header会将上次返回的Etag发送给服务器,询问该资源的Etag是否有更新,有变动就会发送新的资源回来

注:Etag优先级是高于Last-Modifed的,所以服务器会优先验证Etag 具体为什么要用ETag,主要出于下面几种情况考虑:

  1. 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新获取;
  2. 某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒);
  3. 某些服务器不能精确的得到文件的最后修改时间。