强制缓存总体流程比较简单,就是在第一次访问服务器取到数据以后,在过时时间以内不会再去重复请求。实现这个流程的核心就是如何知道当前时间是否超过了过时时间。数据库
强制缓存的过时时间经过第一次访问服务器时返回的响应头获取。在 http 1.0
和 http 1.1
版本中经过不一样的响应头字段实现。浏览器
在 http 1.0
版本中,强制缓存经过 Expires
响应头来实现。 expires
表示将来资源会过时的时间。也就是说,当发起请求的时间超过了 expires
设定的时间,即表示资源缓存时间到期,会发送请求到服务器从新获取资源。而若是发起请求的时间在 expires
限定的时间以内,浏览器会直接读取本地缓存数据库中的信息(from memory
or from disk
),两种方式根据浏览器的策略随机获取。缓存
在 http 1.1
版本中,强制缓存经过 Cache-Control
响应头来实现。Cache-Control
拥有多个值:服务器
private:客户端能够缓存
public:客户端和代理服务器都可缓存;
max-age=xxx:缓存的资源将在 xxx 秒后过时;
no-cache:须要使用协商缓存来验证是否过时;
no-store:不可缓存
最经常使用的字段就是 max-age=xxx
,表示缓存的资源将在 xxx 秒后过时。通常来讲,为了兼容,两个版本的强制缓存都会被实现。代理
强制缓存只有首次请求才会跟服务器通讯,读取缓存资源时不会发出任何请求,资源的 Status
状态码为 200
,资源的 Size
为 from memory
或者 from disk
,http 1.1 版本的实现优先级会高于 http 1.0 版本的实现。code
协商缓存与强制缓存的不一样之处在于,协商缓存每次读取数据时都须要跟服务器通讯,而且会增长缓存标识。在第一次请求服务器时,服务器会返回资源,而且返回一个资源的缓存标识,一块儿存到浏览器的缓存数据库。当第二次请求资源时,浏览器会首先将缓存标识发送给服务器,服务器拿到标识后判断标识是否匹配,若是不匹配,表示资源有更新,服务器会将新数据和新的缓存标识一块儿返回到浏览器;若是缓存标识匹配,表示资源没有更新,而且返回 304
状态码,浏览器就读取本地缓存服务器中的数据。资源
在 http 协议的 1.0
和 1.1
版本中也有不一样的实现方式。ast
在 http 1.0
版本中,第一次请求资源时服务器经过 Last-Modified
来设置响应头的缓存标识,而且把资源最后修改的时间做为值填入,而后将资源返回给浏览器。在第二次请求时,浏览器会首先带上 If-Modified-Since
请求头去访问服务器,服务器会将 If-Modified-Since
中携带的时间与资源修改的时间匹配,若是时间不一致,服务器会返回新的资源,而且将 Last-Modified
值更新,做为响应头返回给浏览器。若是时间一致,表示资源没有更新,服务器返回 304 状态码,浏览器拿到响应状态码后从本地缓存数据库中读取缓存资源。请求
这种方式有一个弊端,就是当服务器中的资源增长了一个字符,后来又把这个字符删掉,自己资源文件并无发生变化,但修改时间发生了变化。当下次请求过来时,服务器也会把这个原本没有变化的资源从新返回给浏览器。总结
在 http 1.1
版本中,服务器经过 Etag
来设置响应头缓存标识。Etag
的值由服务端生成。在第一次请求时,服务器会将资源和 Etag
一并返回给浏览器,浏览器将二者缓存到本地缓存数据库。在第二次请求时,浏览器会将 Etag
信息放到 If-None-Match
请求头去访问服务器,服务器收到请求后,会将服务器中的文件标识与浏览器发来的标识进行对比,若是不相同,服务器返回更新的资源和新的 Etag
,若是相同,服务器返回 304
状态码,浏览器读取缓存。
协商缓存每次请求都会与服务器交互,第一次是拿数据和标识的过程,第二次开始,就是浏览器询问服务器资源是否有更新的过程。每次请求都会传输数据,若是命中缓存,则资源的 Status
状态码为 304
而不是 200
。一样的,通常来说为了兼容,两个版本的协商缓存都会被实现,http 1.1
版本的实现优先级会高于 http 1.0
版本的实现。