用了两天的业余时间,研究了一下缓存的事情,不敢说完全掌握,还是把找的相关资料按照自己的理解整理一下~以供学习,俗话说,好脑子不如烂笔头,跟哪位前辈的重复了,欢迎批评指导,话不说多,步入正题
我们说的缓存指的是可以自动保存常见http请求副本的http设备,有了缓存,我们便可以从本地(浏览器)获取,而不需要在从服务器端更新了;
缓存的分类,网上众说纷纭,但是大致有以下几:,浏览器缓存,CDN缓存,数据库缓存,代理服务器缓存;但本文说的是浏览器缓存.
`我们有时候有个明显的感觉就是,打开某个网站的时候,第一次会感觉慢和卡,第二次会快得多;当然,没有感觉到的话,也可能是网速比较好,感觉到了就是缓存再起作用,第一次请求的时候,下载的数据比较多,第二次往后有缓存(本地副本),就会节约响应时间,
下面列举一下使用缓存(本文指的是浏览器缓存,下文不在赘述)的优点:
1,对用户来说,节约流量,提高了体验性能
2,对网站开发来说,节省带宽,减少冗余的数据传输,另一方面,也降低服务器的压力
一,缓存的示意图如下:
第一次请求的时候是这样的
也不需要过多的解释了,毕竟第一次,啥都要从服务器端获取
2.以后的请求如下图所示
对着流程简单说一下,首先会判断是否有缓存,没有的话,跟第一次一样,去服务器获取;
有的情况下,就要判断缓存时间是否过期,过期了,还要到服务器获取,
没有过期,执行接下来的一步,向服务器发送带有If-None-Match,判断返回的值和ETag是否相等,相等,说明可用缓存,
不相等,向服务器发送带有Ih-Modified-Since,判断和Last-Modified(最后修改时间)两者的时间大小,在决定是使用缓存还是更新.看的懵逼没事,先记住大概流程,接下来一一讲解
二.相关名词解释
1.如何判断时候过期
原来用的是Expires策略,浏览器可以直接从浏览器缓存读取数据,而无需再次请求,它的值对应一个GMT,来告诉浏览器资源缓存过期时间,如果还没过该时间点则不发请求。
例如下面的例子,这是京东的首页里找的一个,时间都干到2027年了,现在的时间是2017年7月20,肯定还没到失效时间,so是304,使用本地缓存,也就是说在失效时间之内,一直使用缓存,除非把缓存删了
但是这是http1.0的东西,现在使用的是http1.1的,这个可以忽略了因为这个是获取的本地的时间,我们改动的话,会出现问题,现在都用Cache-control了
cache-control策略有的地方也叫新鲜度限值
这个和上面说的expires效果是一样的,最大时间,
用来控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。
只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires。
Cache-Control可拥有如下值:
Public
指定响应会被缓存,并且在多用户间共享。
Private
响应只作为私有的缓存(见下图),不能在用户间共享。如果要求HTTP认证,响应会自动设置为private。。缓存只开放给某些特定的用户,比如服务器的用户,其他用户则不能缓存这些数据。
no-cache
指定不缓存响应,表明资源不进行缓存,
no-store
用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存,完全不存下來。
max-age
指示客户端该端时间内缓存都是最新的。单位为秒,就是在这个时间内,不会请求数据了,一直用的就是缓存。比如:Cache-Control:max-age=3600 表示60分钟之后过期,在这60分钟期间不会更新。
min-fresh
指示客户端希望获取一个在小于指定的时间内被更新过的资源,单位为秒:例如:Cache-Control:min-fresh =120 。向服务器获取2分钟内被更新过的资源
max-stale
指示客户端可以接收超出超时期间的响应消息。例如:Cache-Control:max-stale =3600 ,向服务器获取超过缓存时间2分钟的资源..
2.Etag和If-None-Match
下面说的东西,包括Etag和If-None-Match,是在缓存时间已经失效的情况下,即Cache-Control:mac-age = 0 的情况下,
会判断Etag和If-None-Match两者是否相等,ETag是根据实体内容生成的hash字符串,具体是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的,
如果If-None-Match返回的和Etag相等的话,就返回304,可以使用缓存的资源,文件没有被改动.具体如下
3.Last-Modified和If-Modified-Since
在多说一下,这个也是在缓存时间已经失效,即Cache-Control:mac-age = 0 的情况下,而且上面的Etag和If-None-Match不相等的情况下;
Last-Modified指的是文件上一次被修改的时间(可以理解为服务器端的),, 会带着 If-Modified-Since(本地的)返回的时间,,本地的时间大于等于服务器端的时间的花,说明资源没有被改动过接着用缓存的,否则就要更新,从新发送web请求了,如果感觉拗口的话,贴一下参考的原话,
当资源过期时(也就是 Cache-Control:max-age=0,),发现资源具有Last-Modified声明,则再次向web服务器请求时带上头 If-Modified-Since,表示请求时间。web服
务器收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对。若Last-Modified的时间较新,说明最后修改时间较新,说明资源又被改动过,则响应整
的资源重新从服务器读取,而不是读取缓存,返回200状态吗;若If-Modified-Since的时间比Last-Modified新或者相等,说明服务器的内容没有更新,直接读取缓存即可,
返回304状态码,告知浏览器继续使用所保存的cache。
另外需要说明的是: cache-control .Etag和If-None-Match Etag和If-None-Match三者的权重是从左到右越来越小的;
还有一点需要说明的是,我们说的缓存~基本上都是GET方式的,像POST之类的通常情况下是不会进行缓存的;
说了这么多,缓存是好的,可以节约资源,减少服务器的压力,但是,设置太长的缓存时间的话,又不能及时的更新资源,具体如何取舍把握,还要视具体情况再说.