http--->http缓存机制系统梳理
http缓存
HTTP请求的过程
- 从在浏览器地址栏敲入域名-DNS解析-实际IP-(中间可能多个代理服务器分发)- 源服务器,请求抵达源服务器后,在服务器上找到请求的资源,再通过代理服务器一层层的返回数据到浏览器端。
http缓存三要素
-
缓存存储策略
- 用来确定http响应内容是否可以被客户端缓存,以及被哪些客户端缓存
- 对 于 Cache-Control 头里的 Public、Private、no-cache、max-age 、no-store 他们都是用来指明响应内容是否可以被客户端存储的,其中前4个都会缓存文件数据(关于 no-cache 应理解为“不建议使用本地缓存”,其仍然会缓存数据到本地),后者 no-store 则不会在客户端缓存任何响应数据。另关于 no-cache 和 max-age 有点特别,我认为它是一种混合体,下面我会讲到。
- Cache-Control 常见取值是private、public、no-store、no-cache、must-revalidate、max-age等 默认是private(参考:http://www.importnew.com/24907.html)
- 通 过 Cache-Control:Public 设置我们可以将 Http 响应数据存储到本地,但此时并不意味着后续浏览器会直接从缓存中读取数据并使用,为啥?因为它无法确定本地缓存的数据是否可用(可能已经失效),还必须借 助一套鉴别机制来确认才行, 这就是我们下面要讲到的“缓存过期策略”。
- 在没有提供任何浏览器缓存过期策略的情况下,浏览器遵循一个启发式缓存过期策略:
根据响应头中2个时间字段 Date 和 Last-Modified 之间的时间差值,取其值的10%作为缓存时间周期。
-
缓存过期策略
- 决定客户端是否可直接从本地缓存数据中加载数据并展示(否则就发请求到服务端获取)
- 浏览器通过什么条件来判断呢? 答案是:Expires,Expires 指名了缓存数据有效的绝对时间,告诉客户端到了这个时间点(比照客户端时间点)后本地缓存就作废了,在这个时间点内客户端可以认为缓存数据有效,可直接从 缓存中加载展示。
- 不过 Http 缓存头设计并没有想象的那么规矩,像上面提到的 Cache-Control(这个头是在Http1.1里加进来的)头里的 no-cache 和 max-age 就是特例,它们既包含缓存存储策略也包含缓存过期策略
- Cache-Control 中指定的缓存过期策略优先级高于 Expires,当它们同时存在的时候,后者会被覆盖掉。
- 缓存数据标记为已过期只是告诉客户端不能再直接从本地读取缓存了,需要再发一次请求到服务器去确认,并不等同于本地缓存数据从此就没用了,有些情况下即使过期了还是会被再次用到,具体下面会讲到。
-
缓存对比策略
- 客 户端检测到数据过期或浏览器刷新后,往往会重新发起一个 http 请求到服务器,服务器此时并不急于返回数据,而是看请求头有没有带标识( If-Modified-Since、If-None-Match)过来,如果判断标识仍然有效,则返回304告诉客户端取本地缓存数据来用即可(这里要 注意的是你必须要在首次响应时输出相应的头信息(Last-Modified、ETags)到客户端)。至此我们就明白了上面所说的本地缓存数据即使被认 为过期,并不等于数据从此就没用了的道理了。
- If-Modified-Since:告诉服务器只要服务器在这个时间之后又对资源做了修改则发送该资源
- If-None-Match与ETag:根据资源内容是否变更来判断是否继续使用本地缓存。第一次请求资源时,服务器在response头信息中设置ETag,当资源过期后再次向服务器请求时用If-None-Match:ETag去验证资源是否变更
- 当本地缓存过期后,客户端如何知到该使用上述哪种方式呢?其实,在客户端第一次请求资源时,服务器需要带上Last-Modified与ETag,然后缓存起来,当缓存失效重新进行新鲜度检查时,这两个头部就可以派上用场了。一般来说,ETag的优先级高于Last-Modified。
静态内容缓存服务器端配置
- 一般的静态资源例如图片css文件等可以直接通过服务器配置来设置缓存规则
- 不同的服务器配置方式不同,详情可以百度
强缓存和协商缓存
- 强缓存:直接从缓存中获取资源而不经过服务器
- 协商缓存:服务器来确定缓存资源是否可用的,所以客户端与服务器端要通过某种标识来进行通信,从而让服务器判断请求资源是否可以缓存访问
http缓存使用场景
- 静态资源
- 对于那些不经常改变的静态资源,比如CSS、图片、动画等,应尽可能地利用缓存。因为这些资源通常很大而且几乎每个页面可能都会用到,缓存会大大提高系统效率。对于这些资源,响应中应该包含如下内容:
Cache-Control:public; max-age=31536000
Expires: Mon, 25 Jun 2013 21:31:12 GMT
max-age=31536000意味着31536000秒(也就是一年)后缓存失效。这里尤为注意不能设置成多于一年,因为RFC上限制了最大只能是一年,超过一年的情况不同的浏览器处理策略不同,有些直接就忽略了Cache-Control。
- 对于那些不经常改变的静态资源,比如CSS、图片、动画等,应尽可能地利用缓存。因为这些资源通常很大而且几乎每个页面可能都会用到,缓存会大大提高系统效率。对于这些资源,响应中应该包含如下内容:
- 禁用缓存
- 某些情况下需要禁止使用缓存,则应该把Cache-Control设置成"no-cache, no-store",如下所示。
- 私有内容
- 对于需要登录才能访问到资源,Cache-Control应该设置成private以禁止代理服务器缓存这些资源,否则会威胁信息安全。
注意
- 优先级:Cache-Control > Expires > If-Modified-Since.
- POST请求无法被缓存
参考:https://www.cnblogs.com/shangxiaofei/p/6214560.html
https://blog.csdn.net/yzf913214/article/details/52268651
https://segmentfault.com/a/1190000007317481