协商缓存与强缓存简单介绍

协商缓存与强缓存

有多处转载 https://www.jianshu.com/p/fb59c770160c 等

  • 缓存的优点:

    • 减少了不必要的数据传输,节省带宽
    • 减少服务器的负担,提升网站性能
    • 加快了客户端加载网页的速度
    • 用户体验友好
  • 缺点

    • 可能会留下bug

强缓存

  • 当浏览器去请求某个文件的时候,服务端就在respone header里面对该文件做了缓存配置。缓存的时间、缓存类型都由服务端控制
  • respone header 的cache-control,常见的设置是max-age public private no-cache no-store等
  • 强缓存主要包括 expirescache-control

强缓存配置介绍

  • expires

    expiresHTTP1.0 中定义的缓存字段。当我们请求一个资源,服务器返回时,可以在 Response Headers 中增加 expires 字段表示资源的过期时间。

    expires: Thu, 03 Jan 2019 11:43:04 GMT
    
    • 它是一个时间戳(准确点应该叫格林尼治时间),当客户端再次请求该资源的时候,会把客户端时间与该时间戳进行对比,如果大于该时间戳则已过期,否则直接使用该缓存资源。
    • 有个大问题,发送请求时是使用的客户端时间去对比。一是客户端和服务端时间可能快慢不一致,另一方面是客户端的时间是可以自行修改的(比如浏览器是跟随系统时间的,修改系统时间会影响到),所以不一定满足预期。
  • cache-control

    HTTP1.1 新增了 cache-control 字段来解决该问题,所以当 cache-controlexpires 都存在时,cache-control 优先级更高。

    该字段是一个时间长度,单位秒,表示该资源过了多少秒后失效。当客户端请求资源的时候,发现该资源还在有效时间内则使用该缓存,它不依赖客户端时间

    cache-control 主要有 max-ages-maxagepublicprivateno-cacheno-store 等值。

    cache-control: public, max-age=3600, s-maxage=3600 
    
  • max-ages-maxage
    两者是 cache-control 的主要字段,它们是一个数字,表示资源过了多少秒之后变为无效。在浏览器中,max-ages-maxage 都起作用,而且 s-maxage 的优先级高于 max-age。在代理服务器中,只有 s-maxage 起作用。 可以通过设置 max-age 为 0 表示立马过期来向服务器请求资源。

  • publicprivate
    public 表示该资源可以被所有客户端和代理服务器缓存,而 private 表示该资源仅能客户端缓存。

    默认值是 private,当设置了 s-maxage 的时候表示允许代理服务器缓存,相当于 public

  • no-cacheno-store
    no-cache 表示的是不直接询问浏览器缓存情况,而是去向服务器验证当前资源是否更新(即协商缓存)。

    no-store 则更狠,完全不使用缓存策略,不缓存请求或响应的任何内容,直接向服务器请求最新。由于两者都不考虑缓存情况而是直接与服务器交互,所以当 no-cacheno-store 存在时会直接忽略 max-age 等。

强缓存总结

  • cache-control: max-age=xxxx,public
    客户端和代理服务器都可以缓存该资源;
    客户端在xxx秒的有效期内,如果有请求该资源的需求的话就直接读取缓存,statu code:200 ,如果用户做了刷新操作,就向服务器发起http请求
  • cache-control: max-age=xxxx,private
    只让客户端可以缓存该资源;代理服务器不缓存
    客户端在xxx秒内直接读取缓存,statu code:200
  • cache-control: max-age=xxxx,immutable
    客户端在xxx秒的有效期内,如果有请求该资源的需求的话就直接读取缓存,statu code:200 ,即使用户做了刷新操作,也不向服务器发起http请求
  • cache-control: no-cache
    跳过设置强缓存,但是不妨碍设置协商缓存;一般如果你做了强缓存,只有在强缓存失效了才走协商缓存的,设置了no-cache就不会走强缓存了,每次请求都回询问服务端。
  • cache-control: no-store
    不缓存,这个会让客户端、服务器都不缓存,也就没有所谓的强缓存、协商缓存了。

协商缓存

介绍协商缓存

  • 上面说到的强缓存就是给资源设置个过期时间,客户端每次请求资源时都会看是否过期;只有在过期才会去询问服务器。所以,强缓存就是为了给客户端自给自足用的。而当某天,客户端请求该资源时发现其过期了,这是就会去请求服务器了,而这时候去请求服务器的这过程就可以设置协商缓存。这时候,协商缓存就是需要客户端和服务器两端进行交互的。

怎么设置协商缓存?

  • response header里面的设置

    etag: '5c20abbd-e2e8'
    last-modified: Mon, 24 Dec 2018 09:49:49 GMT
    
    • etag:每个文件有一个,改动文件了就变了,就是个文件hash,每个文件唯一,就像用webpack打包的时候,每个资源都会有这个东西,如: app.js打包后变为 app.c20abbde.js,加个唯一hash,也是为了解决缓存问题。
    • last-modified:文件的修改时间,精确到秒
  • 也就是说,每次请求返回来 response header 中的 etag和 last-modified,在下次请求时在 request header 就把这两个带上,服务端把你带过来的标识进行对比,然后判断资源是否更改了,如果更改就直接返回新的资源,和更新对应的response header的标识etag、last-modified。如果资源没有变,那就不变etag、last-modified,这时候对客户端来说,每次请求都是要进行协商缓存了,即:

    发请求–>看资源是否过期–>过期–>请求服务器–>服务器对比资源是否真的过期–>没过期–>返回304状态码–>客户端用缓存的老资源。

  • 当服务端发现资源真的过期的时候,会走如下流程:

    发请求–>看资源是否过期–>过期–>请求服务器–>服务器对比资源是否真的过期–>过期–>返回200状态码–>客户端如第一次接收该资源一样,记下它的cache-control中的max-age、etag、last-modified等。

协商混存总结

  • 请求资源时,把用户本地该资源的 etag 同时带到服务端,服务端和最新资源做对比。
    如果资源没更改,返回304,浏览器读取本地缓存。
    如果资源有更改,返回200,返回最新的资源。

  • response header中的etag、last-modified在客户端重新向服务端发起请求时,会在request header中换个key名:

    // response header
    etag: '5c20abbd-e2e8'
    last-modified: Mon, 24 Dec 2018 09:49:49 GMT
    
    // request header 变为
    if-none-matched: '5c20abbd-e2e8'
    if-modified-since: Mon, 24 Dec 2018 09:49:49 GMT
    

为什么要有etag?

  • 你可能会觉得使用last-modified已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要etag呢?HTTP1.1中etag的出现(也就是说,etag是新增的,为了解决之前只有If-Modified的缺点)主要是为了解决几个last-modified比较难解决的问题:
    • 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新get;
    • 某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),if-modified-since能检查到的粒度是秒级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒);
    • 某些服务器不能精确的得到文件的最后修改时间。

怎么设置强缓存与协商缓存

  • 后端服务器如nodejs:
    • res.setHeader(‘max-age’: ‘3600 public’)
    • res.setHeader(etag: ‘5c20abbd-e2e8’)
    • res.setHeader(‘last-modified’: Mon, 24 Dec 2018 09:49:49 GMT)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值