Http缓存
Http缓存和常规意义上的缓存一致,当有可用的合法缓存时,就可以直接从本地存储设备而不是原始服务器提取.使用缓存有以下优点:
- 减少冗余的数据传送
- 缓解网络瓶颈的问题,更快的加载数据
- 降低原始服务器的要求,更快地响应,避免过载的出现
- 降低距离时延
任何事物都是在变化之中,缓存也一样,对于缓存有两点比较关键
- 缓存的过期时间判断 --- Cache-Control首部和Expires首部
- 缓存的再验证(缓存过期之后的验证) --- 条件方法进行再验证, If-Modified-Since和If-None-Match
一,缓存过期控制
1,Cache-Control和Expires
通过特殊的Httpp Cache-Control首部和Expires首部,Http让原始服务器向每个缓存文件中添加一个"过期时间",在这个缓存文件过期之前,缓存可以任意的使用这个文件.
一旦已缓存文件过期,缓存就必须与服务器进行核对,询问文件是否被修改过,如果被修改过,则需要获取一份新鲜(带有新的过期日期)的副本
2,Cache-Control和Expires的区别
由上图可知,二者的格式是
Expires:Thu, 30 Mar 2017 08:48:17 GMT
Cache-Control:max-age=2592000
这个max-age首部表示的是从服务器将文件传来之时起,可以认为此文件处于新鲜状态的秒数
而这个传来的时间就是Date字段
Date:Tue, 28 Feb 2017 09:09:01 GMT
Expires首部和Cache-Control:max-age首部所做的事情本质上是一样,但是Cache-Control首部使用的是相对时间而不是绝对时间,所以我们更倾向于使用比较新的Cache-Control首部,因为绝对日期依赖于计算机时钟的正确设置.
二,服务器再验证
<一>服务器再验证
已过期的文件并不意味着它和原始服务器上目前处于活跃状态的文件有区别,只是意味着到了要核对的时间了. 服务器再验证,说明缓存需要询问原始服务器文档是否发生了变化
-
如果再验证显示内容发生变化,缓存会获取一份新的文件副本,并将其存储在旧文件的位置上,然后将文件发送给客户端
-
如果再验证显示内容没有变化,缓存只需要获取新的首部,包括一个新的过期时间,并对缓存中的首部进行更新就行了
<二>使用条件方法再验证
1,If-Modify-Since 再验证
If-Modified-Since:Tue, 28 Feb 2017 05:28:08 GMT
If-Modify-Since(IMS)主要是和Last-Modified服务器响应首部结合使用.
-
如果服务端文件未被修改,服务器会向客户端发送一个小的Http 304 Not Modified响应
-
如果服务端文件已被修改,服务器向客户端发送一条普通的,带有完整内容的Http 200 OK响应
-
如果服务端文件已经被删除了,服务器就回送一个404 Not Found响应,缓存也会将其副本删除
2, If-None-Match 实体标签再验证
有些文件可能会周期性地重写,但是包含的数据常常是一样的,尽管内容没有任何变化,但是修改日期会发生变化等等.
为了解决这些问题,HTTP允许用户对被称为实体标签(ETag)的"版本标识符"进行比较.
If-None-Match和ETag配合一起使用
-
如果服务端文件未被修改,服务器会向客户端发送一个小的Http 304 Not Modified响应
-
如果服务端文件已被修改,服务器向客户端发送一条普通的,带有完整内容以及新的ETag的Http 200 OK响应
-
如果服务端文件已经被删除了,服务器就回送一个404 Not Found响应,缓存也会将其副本删除
三,客户端新鲜度验证
1,no-store
Cache-Control:no-store
在请求头中,意味着不使用缓存
在响应头中,意味着不缓存响应
总之,一句话,不使用缓存
2,no-cache与Pragma:no-cache
Cache-Control:no-store
Pragma: no-cache
看这个no-cache理解这个字段会有歧义,字面意思是不使用缓存,这是错误的. 正确的姿势是这样子滴
Cache-Control:no-store的响应可以存储在本地缓存中的.
另外,在与原始服务器进行新鲜度再验证之前,这个缓存是不能提供给客户端使用.
Don't serve from cache without revalidation,这句话就是最好的解释
3, must-revalidate
Control-Cache:must-revalidate
意思是在实现没有跟原始服务器进行再验证的情况下,不能提供和这个对象的副本
4, only-if-cached
Control-Cache:only-if-cached
意味着只能使用本地缓存.
5, max-stale
1)Control-Cache:max-stale
2)Control-Cache:max-stale = <s>
1)缓存可以随意提供过期的文件.
2)如果指定了参数<s>,在这段时间内,文档就不能过期.这条指令范松了缓存的规则
6,min-fresh=<s>
Control-Cache:min-fresh=<s>
至少在未来<s>秒内保持新鲜
7,max-age=<s>
Control-Cache:max-age=<s>
缓存无法返回缓存时间长于<s>秒的文档.
最后附上一个Http缓存使用流程图
Http缓存.png参考
1,RFC2616
2,<<Http权威指南>>