先看上图,若是对图中的(a)(b)(c)(d)四个过程的处理方式都很清楚了,那么请不用再看本文了。css
强缓存
用户发送的请求,直接从客户端缓存中获取,不发送请求到服务器,不与服务器发生交互行为。html
协商缓存
用户发送的请求,发送到服务器后,由服务器断定是否从缓存中获取资源。chrome
二者共同点:客户端得到的数据最后都是从客户端缓存中得到。浏览器
二者的区别:从名字就能够看出,强缓存不与服务器交互,而协商缓存则须要与服务器交互。缓存
先理解个概念,所谓“客户端缓存”就是指用户设备中本地资源。不一样浏览器缓存文件的地址也不尽相同。
咱们以chrome为例来查看下浏览器缓存文件的地址,
1)首先在chrome中输入:chrome://chrome-urls/,看到一堆列表,里面隐藏了许多浏览器的奥秘,有兴趣的能够本身深扒。
2)找到 chrome://cache(固然也能够直接输入这个地址)
为了验证缓存,咱们打开百度,打开开发者模式,去掉disable-cache选项
服务器
从上图中能够看到,第一个从缓存中取的文件是: https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/css/super_min_fec0412a.css
而后回到chrome://cache 页面,找到它,并点击进去,能够看到:
回到问题,浏览器怎么断定是否有缓存,就能够转化为浏览器去读取本地放缓存的地方(注:不一样浏览器不一样系统都会不一样)是否有该对应的请求啦。负载均衡
咱们再以这张图为例,这张图中代表,客户端保留了一个服务器端的response header。
里面的Date字段代表这次缓存时服务器的时间。
里面有两个字段:expires 、Cache-Control分布式
expires
Http1.0 中的标准,代表过时时间,注意此处的时间都是指的是服务器的时间。
能够看到过时时间被设定为了:Thu, 28 Sep 2017 06:38:37 GMTurl
Cache-Control
Http1.1 中的标准,能够当作是 expires 的补充。使用的是相对时间的概念。
简单介绍下Cache-Control的属性设置。
1)max-age: 设置缓存的最大的有效时间,单位为秒(s)。max-age会覆盖掉Expires
2) s-maxage: 只用于共享缓存,好比CDN缓存(s -> share)。与max-age 的区别是:max-age用于普通缓存,
而s-maxage用于代理缓存。若是存在s-maxage,则会覆盖max-age 和 Expires.
3) public:响应会被缓存,而且在多用户间共享。默认是public。
4) private: 响应只做为私有的缓存,不能在用户间共享。若是要求HTTP认证,响应会自动设置为private。
5)no-cache: 指定不缓存响应,代表资源不进行缓存。可是设置了no-cache以后并不表明浏览器不缓存,而是在缓存前要向服务器确认资源是否被更改。所以有的时候只设置no-cache防止缓存仍是不够保险,还能够加上private指令,将过时时间设为过去的时间。
6)no-store: 绝对禁止缓存。
7)must-revalidate: 若是页面过时,则去服务器进行获取。
设置cache-control 的规则能够参见下图:
3d
因此判断缓存是否过时步骤是:
1) 查看是否有cache-control 的max-age / s-maxage , 若是有,则用服务器时间date值 + max-age/s-maxage 的秒数计算出新的过时时间,将当前时间与过时时间进行比较,判断是否过时
2)查看是否有cache-control 的max-age / s-maxage,则用expires 做为过时时间比较
到这一步的时候,浏览器会向服务器发送请求,同时若是上一次的缓存中有Last-modified 和 Etag 字段,
浏览器将在request header 中加入If-Modified-Since(对应于Last-modified), 和If-None-Match(对应于Etag)。
If-None-Match: 客户端保留的资源内容标识。
1) 分布式系统尽可能关闭Etag,由于每台机器生成的Etag都不同。
2)分布式系统里多台机器间文件的Last-Modified必须一致,以避免负载均衡不一样致使对比失败。
一般状况下,若是同时发送 If-None-Match 、If-Modified-Since字段,服务器只要比较etag 的内容便可,固然具体处理方式,看服务器的约定规则。
在这个阶段,服务器通常会将Cache-control、expires 、last-modified、date、etag 等字段在response header 中返回,便于下次缓存。固然具体的场景,也是看服务器的约定规则设定。
⚠️: 这个问题暂时没有找到很是满意的、清楚的回答。
从磁盘中获取缓存资源,等待下次访问时不须要从新下载资源,而直接从磁盘中获取。它的直接操做对象为CurlCacheManager。
从内存中获取资源,等待下次访问时不须要从新下载资源,而直接从内存中获取。Webkit早已支持memoryCache。
目前Webkit资源分红两类,一类是主资源,好比HTML页面,或者下载项,一类是派生资源,好比HTML页面中内嵌的图片或者脚本连接,分别对应代码中两个类: MainResourceLoader和SubresourceLoader。虽然Webkit支持memoryCache,可是也只是针对派生资源,它对应的类为CachedResource,用于保存原始数据(好比CSS,JS等),以及解码过的图片数据。
当退出进程时,内存中的数据会被清空,而磁盘的数据不会,因此,当下次再进入该进程时,该进程仍能够从diskCache中得到数据,而memoryCache则不行。
diskCache与memoryCache类似之处就是也只能存储一些派生类资源文件。它的存储形式为一个index.dat文件,记录存储数据的url,而后再分别存储该url的response信息和content内容。Response信息最大做用就是用于判断服务器上该url的content内容是否被修改。
最后附上一张,用户行为影响浏览器的缓存行为。
自此能够将本文开头的流程图理解清楚。
Chrome浏览器的缓存文件位置: http://jingyan.baidu.com/article/f3e34a128e41acf5ea653554.html
浏览器缓存机制:http://www.cnblogs.com/skynet/archive/2012/11/28/2792503.html
浏览器缓存知识小结及应用: http://mp.weixin.qq.com/s/HRrYWnZIWgE_Hawr81CZTw
200 ok 几种状态:http://www.cnblogs.com/tangyuu/p/6396644.html