浏览器缓存机制

20 篇文章 1 订阅

本文转载自

http://blog.csdn.net/longxibendi/article/details/41630389

http://www.2cto.com/kf/201608/532286.html

浏览器端的缓存规则


           对于浏览器端的缓存来说,这些规则是在HTTP协议头和HTML页面的Meta标签中定义的。他们分别从新鲜度和校验值两个维度来规定浏览器是否可以直接使用缓存中的副本,还是需要去源服务器获取更新的版本。
         新鲜度(过期机制):也就是缓存副本有效期。一个缓存副本必须满足以下条件,浏览器会认为它是有效的,足够新的:

         含有完整的过期时间控制头信息(HTTP协议报头),并且仍在有效期内;

         浏览器已经使用过这个缓存副本,并且在一个会话中已经检查过新鲜度;

        满足以上两个情况的一种,浏览器会直接从缓存中获取副本并渲染。


        校验值(验证机制):服务器返回资源的时候有时在控制头信息带上这个资源的实体标签Etag(Entity Tag),它可以用来作为浏览器再次请求过程的校验标识。如过发现校验标识不匹配,说明资源已经被修改或过期,浏览器需求重新获取资源内容。


浏览器缓存的控制

     

        上述代码的作用是告诉浏览器当前页面不被缓存,每次访问都需要去服务器拉取。使用上很简单,但只有部分浏览器可以支持,而且所有缓存代理服务器都不支持,因为代理不解析HTML内容本身。

        使用缓存有关的HTTP消息报头
        在HTTP请求和响应的消息报头中,常见的与缓存有关的消息报头有:

       

         Cache-Control与Expires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires。

                                                   

           对于上图中的响应头来说:
          Date是当前时间,Expires规定了缓存失效时间(日期),而Cache-Control的max-age规定了缓存有效时间(距离失效的秒数),理论上这两个值计算出的有效时间应该是相同的。Expires属于HTTP1.0,而Cache-Control属于HTTP1.1
注意:

          **规定如果max-age和Expires同时存在,Cache-Control优先级高于Expires。

          **Cache-Control的参数可以设置很多值


http协议头Cache-Control:

      值可以是public、private、no-cache、no- store、no-transform、must-revalidate、proxy-revalidate、max-age
各个消息中的指令含义如下:
        Public        指示响应可被任何缓存区缓存。
        Private       指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效。
       no-cache    指示请求或响应消息不能缓存
       no-store      用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。
       max-age     指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。
       min-fresh    指示客户机可以接收响应时间小于当前时间加上指定时间的响应。
       max-stale   指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。


Last-Modified和ETag与Cache-Control和Expires

         配置Last-Modified/ETag的情况下,浏览器再次访问统一URI(统一资源标识符)的资源,还是会发送请求到服务器询问文件是否已经修改,如果没有,服务器会只发送一个304回给浏览器,告诉浏览器直接从自己本地的缓存取数据;如果修改过,那就最新的文件发给浏览器;
        Cache-Control/Expires则不同,如果检测到本地的缓存还是有效的时间范围内,浏览器直接使用本地副本,不会发送任何请求。两者一起使用时,Cache-Control/Expires的优先级要高于Last-Modified/ETag。即当本地副本根据Cache-Control/Expires发现还在有效期内时,则不会再次发送请求去服务器询问修改时间(Last-Modified)或实体标识(Etag)了。
        注意:一般情况下,需要Cache-Control/Expires配合Last-Modified/ETag一起使用,因为即使服务器设置缓存时间, 当用户点击“刷新”按钮时,浏览器会忽略缓存继续向服务器发送请求,这时Last-Modified/ETag将能够很好利用304,从而减少响应开销(这里只是避免了服务器响应数据,也就是说如果响应304。服务不再返回数据,浏览器直接使用缓存文件,但是浏览器端依旧会发送请求)。


Last-Modified与If-Modified-Since

          Last-Modified/If-Modified-Since就是上面说的当有效期过后,check服务端文件是否更新的第一种方式, 要配合Cache-Control使用。比如响应头信息:

                                                                             

         按下ctrl+r刷新,因为ctrl+r会默认跳过max-age和Expires的检验直接去向服务器发送请求,看下图:

                                                                         

         请求头中包含了If-Modified-Since项,而它的值和上次请求响应头中的Last-Modified一致,我们发现这个日期是2013年,也就是说这个文件自从2013年的那个日期后就没有再被修改过了。


ETag与If-None-Match

        ETag/If-None-Match是第二种check服务端文件是否更新的方式,也要配合Cache-Control使用。实际上ETag并不是文件的版本号,而是一串可以代表该文件唯一的字符串(Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。),当客户端发现和服务器约定的直接读取缓存的时间过了,就在请求中发送If-None-Match选项,值即为上次请求后响应头的ETag值,该值在服务端和服务端代表该文件唯一的字符串对比(如果服务端该文件改变了,该值就会变),如果相同,则响应HTTP304,客户端直接读取缓存,如果不相同,则响应HTTP200,下载正确的数据,更新ETag值。

                                                                                                                                  

                                                                                 

         结合上图来说:当浏览器缓存过期之后,客户端就会重新向服务器发送请求,请求头中带If-None-Match项,该字符串值会在服务端进行匹配,很显然,并没有什么变化(对比响应头的ETag值),于是响应HTTP304,直接读取缓存。
         细心的你或许发现了:该请求中也有If-Modified-Since项,如果两者同时存在,If-None-Match优先,忽略If-Modified-Since。或许你会问为什么它优先?两者功能相似甚至相同,为什么要同时存在?HTTP1.1中ETag的出现主要是为了解决几个Last-Modified比较难解决的问题:
         Last-Modified标注的最后修改只能精确到秒,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间 如果某些文件会被定期生成,但有时内容并没有任何变化(仅仅改变了时间),但Last-Modified却改变了,导致文件没法使用缓存, 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形
         Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。

      

用户操作行为与缓存 

                                           

           通过上表我们可以看到,当用户在按F5进行刷新的时候,会忽略Expires/Cache-Control的设置,会再次向服务器发送请求,而Last-Modified/Etag还是有效的,服务器会根据情况判断返回304还是200;而当用户使用Ctrl+F5进行强制刷新的时候,所有的缓存机制都将失效,重新从服务器获取资源。



哪些请求不能被缓存?

无法被浏览器缓存的请求:

        1.HTTP信息头中包含Cache-Control:no-cache,pragma:no-cache,或Cache-Control:max-age=0等告诉浏览器不用缓存的请求
        2.需要根据Cookie,认证信息等决定输入内容的动态请求是不能被缓存的
        3.经过HTTPS安全加密的请求(有人也经过测试发现,ie其实在头部加入Cache-Control:max-age信息,firefox在头部加入Cache-Control:Public之后,能够对HTTPS的资源进行缓存,参考《HTTPS的七个误解》)

       4.POST请求无法被缓存

       5.HTTP响应头中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的请求无法被缓存


小结



上图对于浏览器缓存机制描述的很详细,这里我对其做了一下语言描述。
个人理解,如有错误,请指正
         当客户端向服务器发送一个请求时,首先检查是否存在缓存,有缓存文件则判断缓存文件是否过期,如果缓存文件没有过期,则直接从缓存中读取文件。
          如果缓存文件过期,则查看响应头中是否存在Etag,如果不存在,则继续查看响应头中是否存在Last-Modified,如果也不存在,则直接向服务器发送新的请求,等待请求响应,缓存协商,呈现页面。
          如果缓存文件过期,响应头中存在ETag,向服务器发送带If-None-Match的请求,值即为上次请求后响应头的ETag值,该值在服务端和服务端代表该文件唯一的字符串对比(如果服务器端该文件更新了,该值就会变),如果相同,则响应HTTP304,客户端直接读取缓存文件,如果不相同,则响应HTTP200,服务器返回最新的文件,同时更新ETag值。
        如果缓存文件过期,响应头中不存在Etag,但是存在Last-Modified,则向服务器发送带If-Modified-Since的请求,将If-Modified-Since的日期和服务端该文件的最后修改日期对比,如果两个日期相同,则响应HTTP304,客户端直接读取缓存文件;如果不相同则表示文件发生变化更新,响应HTTP200,从服务器返回最新的文件数据,同时更新响应头last-Modified的值(以备下次对比)。

======================================================================================

操作  
 行为
打开新窗口        如果指定cache- control的值为private、no-cache、must-revalidate,那么打开新窗口访问时都会重新访问服务器。而如果指定了 max-age值,那么在此值内的时间里就不会重新访问服务器,例如:Cache-control: max-age=5 表示当访问此网页后的5秒内再次访问不会去服务器.
在地址栏回车        如果值为private或must-revalidate,则只有第一次访问时会访问服务器,以后就不再访问。如果值为no-cache,那么每次都会访问。如果值为max-age,则在过期之前不会重复访问。
按后退按扭        如果值为private、must-revalidate、max-age,则不会重访问,而如果为no-cache,则每次都重复访问.
按刷新按扭       无论为何值,都会重复访问.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值