介绍HTTP缓存机制之前还是先将一下HTTP报文作为知识铺垫
HTTP报文就是浏览器和服务器之间通信时发送以及相应的数据块,浏览器向服务器请求数据时,会发送请求(request)报文,浏览器返回数据,返回相应(response)报文。
报文信息主要包括两部分
1.包含属性的首部(header),附加信息(缓存以及缓存的规则等。。。。)
2.包含数据的主体部分(body),请求的数据或者是浏览器返回的相应数据
缓存规则
为了方便理解,我们假设浏览器本身存在一个缓存数据库,用来存储数据
当浏览器第一次向服务器请求数据时,浏览器缓存中并没有数据,因此浏览器向服务器请求,服务器做出相应,返回相应的数据给浏览器,同时也将该数据存在浏览器缓存中。流程图如下:
HTTP缓存有多种规则,可以根据是否重新向服务器发送请求将缓存规则分为两种(强制缓存和对比缓存)
注:1.强制缓存的优先级高于对比缓存
2.强制缓存和对比缓存都可同时存在,但一般执行强制缓存的规则的时候,若缓存存在,则不再执行对比缓存
1.强制缓存:当缓存数据库存在数据且缓存未失效的情况下,浏览器会直接从缓存数据库取数据,而不再请求服务器;当缓存数据库没数据或者缓存失效的情况下,浏览器会请求服务器,服务器返回数据并放在缓存数据库中。
那么怎么判断缓存是否失效了呢,我们知道第一次请求服务器时,服务器将相应数据和缓存规则都一并返还给浏览器,其中缓存规则就放在header中
对于强制缓存来说,相应header中会有两个字段来标识其失效规则(Expires/Cache-Control)
Expires
Expires值为服务器返回的一个到期时间,当下次请求时,请求时间若小于Expires值,则可以直接使用缓存数据库的数据
但1.Expires是HTTP1.0的东西了,现在所有的浏览器默认都是HTTP1.1了;
2.Expires是服务器返回的服务器时间,而请求时间是本地时间,两者的时间可能存在差异,导致缓存命中的误差
故,现在几乎都不用Expires了,这里提一下,让大家了解一下
Cache-Control
Cache-Control常见的取值有private、public、no-cache、max-age,no-store,默认为private。
public,private和no-store就不用说了,重点说说no-cache,顺带提一下max-age
先讲讲max-age:
图中Cache-Control仅设置了max-age,也就是默认为private,max-age=31536000(365天),表示接下来的365天都是直接从缓存数据库取数据,不用请求服务器了。
看到这里,可能有人会问不是设置了max-age了吗,怎么还默认private。请看清楚每个参数代表的什么意思,并不是说设置了一个值,其他的都不能存在了,设置了max-age,那么过了这个时间呢,用什么缓存规则呢,所以还能使用其他的,上面的注意事项里提过了。
如下图,设置了时间,过了这个时间以后,执行强制缓存,发现缓存失效了,就执行对比缓存的规则,下图的Etag和Last-Modified就是对比缓存的两个标识,下面会继续讲
2.对比缓存:顾名思义就是对比一下,看缓存数据库的缓存能否被直接使用,每次对比都是请求服务器进行对比,相对于强制缓存而言,对比缓存每次都得请求服务器
浏览器第一次请求服务器时,服务器会将缓存标识和相应的数据都返回个浏览器,浏览器将二者都缓存到数据库,当第二次请求时,浏览器会将缓存标识取出,传递给服务器,服务器进行判断,若比较成功则会返回304状态码,表示可以使用缓存数据库的数据,则浏览器从缓存数据库取数据,若比较失败,则会重新返回新的数据和新的缓存标识给浏览器,同时也保存到浏览器缓存
对于对比缓存来说,缓存标识的传递是我们着重需要理解的,它在请求header和响应header间进行传递,一共分为两种标识传递,接下来,我们分开介绍。
Last-Modified / If-Modified-Since
Last-Modified:服务器相同相应请求时,告诉浏览器资源的最后修改时间
If-Modified-Since:再次请求服务器时,通过此字段通知服务器上次请求时返回的资源最后修改时间,
服务器收到请求后发现请求头有If-Modified-Since,则与被请求的资源的最后修改时间进行对比,
若资源的最后修改时间大于If-Modified-Since,则说明资源改动过,则响应整片资源内容,返回整片内容,
返回状态码200;
若资源最后修改时间小于或等于If-Modified-Since,则说明资源无新修改,则返回状态码304,告诉浏览器可以继续使用缓存数据库的数据
Etag / If-None-Match(优先级高于Last-Modified / If-Modified-Since)
Etag:服务器相应请求时,告诉浏览器当前资源在服务器的唯一标识,该标识的生成规则由浏览器决定
If-None-Match:当再次请求服务器时,服务器发现请求头有If-None-Match,则与被请求资源的唯一标识进行比较,
若两者一样,则说明资源未改动,返回状态码304,告诉浏览器可继续使用缓存数据库的数据
若不一样,则说明资源改动,响应整片资源给浏览器,返回状态码200
总结:
对于强制缓存,当处于缓存时间内,则直接使用浏览器的缓存数据,若处于时间外,则使用对比缓存
对于对比缓存,将缓存信息中的If-Modified-Since,If-None-Match发送服务器,若返回状态码304,则继续使用浏览器缓存