浏览器缓存机制

浏览器的缓存机制也就是我们说的HTTP缓存机制,其机制是根据HTTP报文的缓存标识进行的。

        一个数据请求可以分为发起网络请求、后端处理、浏览器响应三个步骤。浏览器缓存可以帮助我们在第一和第三步骤中优化性能。比如说直接使用缓存而不发起请求,减少客户端和服务器之间的请求次数,或者发起了请求但后端存储的数据和前端一致,那么就没有必要再将数据回传回来,这样就减少了响应数据,减少网络负荷。总之浏览器缓存可以减少带宽、减少客户端和服务器之间通信的时延,提高性能和用户体验。具体过程如下:

 

        浏览器每次发起请求,都会先在浏览器缓存中查找该请求结果以及缓存标识,浏览器每次拿到返回的请求结果都会将该结果和缓存标识存入浏览器缓存中。客户端第一次向服务器请求数据时,服务器会将缓存规则放入HTTP响应报文的HTTP头中和请求结果一起返回给浏览器,客户端会缓存到内存或者硬盘当中,再进行第二次获取相同的资源,通过浏览器缓存策略决定如何获取相应数据,通常浏览器缓存策略分为两种:强缓存协商缓存,并且缓存策略都是通过设置HTTP Header 来实现的。 

强制缓存

        强制缓存是当客户端第二次向服务器请求相同的资源时,不会向服务器发送请求,而是直接从缓存中读取,控制强缓存的HTTP Header字段分别是ExpiresCache-Control,其中Cache-Conctrol的优先级比Expires高。

1.Expires
  • Expires用来指定资源到期的时间,是服务器端的具体的时间点,即Expires=max-age + 请求时间,需要和Last-modified结合使用。

        它控制缓存的原理是使用客户端的时间与服务端返回的时间做对比,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。

        Expires 是 HTTP/1 的产物,受限于本地时间,如果修改了本地时间,可能会造成缓存失效。到了HTTP/1.1,Expires已经被Cache-Control替代

2.Cache-Control

        在HTTP/1.1中,Cache-Control是最重要的规则,主要用于控制网页缓存,可以在请求头或者响应头中设置,并且可以组合使用多种指令,主要取值为:

(1) 是否缓存

  • no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存;
  • no-cache:客户端缓存内容,是否使用缓存则需要经过协商缓存来验证决定。表示不使用 Cache-Control的缓存控制方式做前置验证,而是使用 Etag 或者Last-Modified字段来控制缓存。注意:no-cache这个名字有一点误导。设置了no-cache之后,并不是说浏览器就不再缓存数据,只是浏览器在使用缓存数据时,需要先确认一下数据是否还跟服务器保持一致。

(2) 是否共享缓存

  • private:所有内容只有客户端可以缓存,Cache-Control的默认值
  • public:所有内容客户端和代理服务器都可缓存,在下次再请求同一资源代理服务器可以直接把自己缓存的东西给浏览器而不再向服务器请求。

(3) 缓存有效时长

  • max-age:用于普通缓存,max-age=xxx (单位为s)表示缓存内容将在xxx秒后失效;
  • s-maxage(单位为s):用于代理缓存,只在代理服务器中生效(比如CDN缓存),同max-age作用一样。s-maxage的优先级高于max-age。
  • max-stale:能容忍的最大过期时间。max-stale指令标示了客户端愿意接收一个已经过期了的响应。如果指定了max-stale的值,则最大容忍时间为对应的秒数。如果没有指定,那么说明浏览器愿意接收任何age的响应(age表示响应由源站生成或确认的时间与当前时间的差值)。
  • min-fresh:能够容忍的最小新鲜度。min-fresh标示了客户端不愿意接受新鲜度不多于当前的age加上min-fresh设定的时间之和的响应。

        多个指令可以配合起来一起使用,以达到多个目的,它们之间的优先级顺序如图所示:

 

协商缓存

        协商缓存是当客户端第二次向服务器请求相同的资源时,在强缓存失效后,浏览器携带缓存标识向服务器发起请求,"询问"该请求的文件缓存在本地与服务器相比是否更改,如果更改,则更新文件,如果没有就从缓存中读取。可以通过设置两种 HTTP Header 实现:Last-Modified Etag

1.Last-Modified和If-Modified-Since
  • Last-Modified:浏览器在第一次访问资源的情况下,服务器会在返回资源的同时,在响应头中添加Last-Modified的headerLast-Modified的值是这个资源在服务器上的最后修改时间,浏览器接收后,缓存这个文件和header。
  • If-Modified-Since:浏览器再次请求这个资源,浏览器检测到有 Last-Modified这个header,于是浏览器添加If-Modified-Since这个header(请求头),值就是Last-Modified的值。服务器再次收到这个资源请求,会根据 If-Modified-Since 中的值与服务器中这个资源的最后修改时间对比。如果If-Modified-Since的时间大于等于服务器中这个资源的最后修改时间,说明资源无新修改,即有效返回状态码304和空的响应体,直接从缓存读取。如果If-Modified-Since的时间小于服务器中这个资源的最后修改时间,说明文件有更新,即失效,于是返回新的资源文件和状态码200。

        Last-modified只精确到秒,如果在一秒钟内修改多次文件,将无法准确拿到最新的文件。如果缓存文件,打开后但是不修改内容,会导致Last-modified发生变化,下一次服务端就不能命中缓存导致发送相同的资源,在HTTP / 1.1 出现了 ETag 和 If-None-Match来解决这个问题。

 2.ETag和If-None-Match
  •  ETag:它是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成,响应头),只要资源有变化,Etag就会重新生成。直接根据文件内容是否修改来决定缓存策略。
  • If-None-Match:浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的Etag值放到请求头里的If-None-Match里,服务器只需要比较客户端传来的If-None-Match跟自己服务器上该资源的ETag值是否一致,就能很好地判断资源相对客户端而言是否被修改过了。若一致,直接返回304知会客户端直接使用本地缓存即可,若不一致,那么直接以常规GET 200回包形式将新的资源(当然也包括了新的ETag)发给客户端。

        Etag在精度上要优于Last-Modified,当在请求头中会先进行ETag比较,然后再进行Last-modified比较,Etag的优先级要高于Last-modified,如果两者都相等,则直接返回304,直接使用缓存资源。

优先级

           强制缓存                 >             协商缓存

cache-control > Expirse     >    Etag > Last-Modified

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值