我们假设浏览器在请求一张图片:
我们拿百度首页来举例: 百度搜索输入框上面的logo是一张png图片,当我们浏览器请求这张图片的时候,会先检查该图片的HTTP头部字段,是这样的
其中,Expires和Cache-Control这两个响应头部字段都可以控制该图片在浏览器缓存的有效期。
Expires
Expires: Fri, 25 May 2029 13:53:52 GMT (必须是GMT格式的时间)
Cache-Control 部分说明:
Public 指示响应可被任何缓存区缓存。 Private 指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效。 no-cache 指示请求或响应消息不能缓存(HTTP/1.0用Pragma的no-cache替换) no-store 用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。 max-age 指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。 min-fresh 指示客户机可以接收响应时间小于当前时间加上指定时间的响应。 max-stale 指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。
Expires是HTTP1.0的时候提出来的,他的时间是一个绝对时间,而Cache-Control是HTTP1.1提出来的,他的时间是一个相对时间。
Expires:
Cache-Control: 和Expires不同之处就在时间那一块,Cache-Control计算的是一个相对时间。当浏览器第二次请求的时候会去缓存中寻找该图片,然后会根据第一次获取到该图片的时间和max-age的时间计算出一个相对的过期时间,如果当前时间没有超过这个过期时间,则使用缓存的资源。
此外,有一点需要注意的是Expires和Cache-Control可以同时存在,如果同时存在的话,后者的优先级更高。
假设我们还是加载一张图片,当我们不满足强缓存的时候就会给服务器发送一个请求,然后会根据协商缓存的几个头部字段判断是否满足协商缓存,如果满足,就会返回304状态码以及Not Modified短语。
靠时间来判断资源是否更新是很不可靠的,于是就有了更加可靠的ETag和If-None-Match,他们是直接判断实际内容是否有变化。
从缓存位置上来说分为四种,并且各自有优先级。
Service Worker是独立运行在浏览器里面的线程,是一个可以自由控制缓存文件的机制,一般经过Service Worker寻找缓存的请求,无论最终是在哪儿取到的资源,在浏览器网络窗格中显示的都是Service Worker。
Memory Cache,就是将资源缓存到内存中,等待下次访问时不需要重新下载资源,而直接从内存中获取。Webkit早已支持Memory Cache。 目前Webkit资源分成两类,一类是主资源,比如HTML页面,或者下载项,一类是派生资源,比如HTML页面中内嵌的图片或者脚本链接。虽然Webkit支持Memory Cache,但是也只是针对派生资源,用于保存原始数据(比如CSS,JS等),以及解码过的图片数据。
Disk Cache,就是将资源缓存到磁盘中,等待下次访问时不需要重新下载资源,而直接从磁盘中获取。它与Memory Cache最大的区别在于,当退出进程时,内存中的数据会被清空,而磁盘的数据不会,所以,当下次再进入该进程时,该进程仍可以从diskCache中获得数据,而Memory Cache则不行。 Disk Cache与Memory Cache相似之处就是也只能存储一些派生类资源文件。它的存储形式为一个index.dat文件,记录存储数据的url,然后再分别存储该url的response信息和content内容。
Push Cache(推送缓存)是 HTTP/2 中的内容,当以上三种缓存都没有命中时,它才会被使用。它只在会话(Session)中存在,一旦会话结束就被释放,并且缓存时间也很短暂,在Chrome浏览器中只有5分钟左右,同时它也并非严格执行HTTP头中的缓存指令。