『图解HTTP』及『HTTP权威指南』关于缓存知识的笔记及总结。
缓存的优点
减少冗余的数据传输,节省网路费用
缓解了网络瓶颈的问题,不需要更多的带宽就能够更快的访问页面
降低了原始服务器的压力,避免过载的出现
降低了距离时延,从较远的地方加载页面速度会更快一些
缓存的命中
分为三种情况:
缓存命中
直接从缓存中获取资源,不需要给服务器发送HTTP请求,这种情况下速度最快。status是from cache
缓存再验证命中
向服务器发送一个请求来验证缓存是否过期,如果没过期,服务器返回304 Not Modified进行响应。客户端得到的仍然是缓存中的资源。
缓存再验证未命中
服务器的资源与缓存副本不同,服务器向客户端发送带有完整内容的HTTP 200 OK的响应。相比于上述的304,传输的内容要更多一些。
资源被删除
如果服务器改资源已删除,则发送一个404 Not Found响应,缓存也会将其副本删除。
缓存的拓扑结构
私有缓存是个人的缓存,包含单个用户最常用的页面。比如浏览器内建的私有缓存。
公有缓存是共享的缓存,包含某个用户团体的常用页面。
公有代理缓存是特殊的共享代理服务器,从本地缓存中获取资源,或者代表用户与服务器进行联系。可以接受来自多个用户的访问,更好地减少冗余流量。
代理缓存的层次结构采用多层次的缓存结构,基本思想是在靠近客户端的地方使用小型廉价缓存,而更高层次中,则逐步采用更大,功能更强的缓存来装载多用户共享的文档。
浏览器自带的缓存也是其中一个层次
缓存的处理步骤
接收
缓存从网络中读取抵达的请求报文。
解析
缓存将请求报文解析为片段,将首部的各个部分放入易操作的数据结构。这样,缓存软件就更容易处理首部字段并修改他们。
查找
缓存获取了URL,查找本地副本。本地副本可能存在内存,本地磁盘甚至附近的一台计算机中。如果本地没有这个文档,它可以根据情形和配置,到原始服务器或代理中去获取,或者返回错误信息。
新鲜度检测
缓存文件在有效期内都认为是新鲜的,缓存可以在不联系服务器的情况下,直接提供改文档。一旦缓存停留的时间过长,超出了文档的『新鲜度』,缓存就要与服务器进行确认,以查看改文档是否发生了变化。
创建响应
缓存的响应看起来像来自原始服务器一样,缓存将已缓存的服务器响应首部作为响应首部的起点,然后缓存对这些基础首部进行了修改和扩充。
发送
一旦响应首部准备好了,缓存就会将响应回送给客户端。
日志
大多数缓存都会保存日志文件及与缓存的使用有关的一些统计数据。
缓存的再验证
If-Modified-Since: Date再验证
If-Modified-Since
首部与Last-Modified
服务器响应首部配合工作。当缓存要对已缓存文档进行再验证时,就会包含一个If-Modified-Since
的首部,其中携带有最后修改已缓存副本的日期。如果缓存是新鲜的,就回返回304 Not Modified响应。
注意有些Web服务器并没有将If-Modified-Since
作为真正的日期来进行比较,而是进行字符串匹配。
If-None-Match: 实体标签再验证
有些情况下仅使用最后修改日期是不够的:
内容没变,修改日期会发生变化。
有些文被修改了,但所做修改不重要,不需要让世界范围内的缓存都重装数据。
有些服务器无法准确判定文件的最后修改日期。
有些服务器提供的文档会在亚秒间隙内发生变化,以秒为粒度的修改日期就不够用了。
为了解决以上问题,引入了实体标签(ETag)的『版本标识符』进行比较。
If-None-Match
属于请求头字段,如果服务器判定到If-None-Match
与请求资源的ETag一致,则不处理请求,返回304,客户端可直接使用缓存。
ETag
是服务器响应头部信息。
如果最后修改日期和实体标签都提供了,就应该使用这两种方案。只有都通过了才能使用缓存资源。
缓存的控制
Cache-Control
Cache-Control
是请求和响应的通用首部字段,能够控制缓存的行为。
常见的一些取值及代表的含义
no-cache
该指令目的是防止使用缓存中过期的资源。
如果请求头部包含no-cache指令,表示客户端不接收缓存过的响应。中间缓存服务器必须将请求转发给给源服务器。
浏览器强制刷新(window下ctrl+F5)就是这个原理,所以的请求都设置no-cache。
如果服务器返回的响应中包含no-cache指令,从字面意思很容易误解未不缓存,但事实no-cache是可以存储在本地缓存中的,但在每次提供给客户端使用之前,需要与原始服务器进行新鲜度验证。
Pragma: no-cache
兼容HTTP/1.0+ ,要求所有的中间服务器不提供缓存。
no-store
使用no-store
指令,暗示请求和响应包含机密信息,不能进行缓存。
区分与no-cache的区别,no-store才是真正的不缓存
max-age
该指令用来标识缓存资源的最大有效期。
当请求头部中包含max-age
,如果缓存资源的缓存时间比指定数值小即表明缓存是有效的,那么客户端就接收缓存的资源,不会向源服务器发送请求。
不会向源服务器发送请求,这是一个很重要的点,可以用于网站的优化。
如果max-age=0
,就会向源服务器发送请求进行缓存资源新鲜度的验证。浏览器普通刷新F5
当服务器响应头部中包含max-age
,其数值标识缓存的最长时间,在这个时间内缓存服务器不再对资源进行新鲜度验证。
s-maxage
其行为与maxage
类似,仅适用于公有缓存。
有一个点总结下:在请求头中
max-age=0
与no-cache
的区别?
返回的状态来看:no-cache
都是200,而max-age
可能是304(如果浏览器有缓存)。
请求参数:max-age
请求头一般会携带If-Modified-Since
或If-None-Match
字段进行新鲜度验证,而no-cache
不会携带。
F5刷新是max-age=0
来实现,而强制刷新(Ctrl+F5)是通过no-cache
实现。
Expires
Expires
是HTTP 1.0+的首部,用来指定一个绝对的过期日期,依赖客户端时间设置的准确性。
而max-age
是HTTP/1.1的Cache-Control
的一个字段,用来指定文档的最大使用时间。
试探性过期
如果响应中既没有包含Cache-Control:max-age
首部,也没有Expires
首部,缓存可以计算出一个试探性最大使用日期。
LM-Factor
算法一种常用的试探性过期算法,该算法将最后修改日期作为依据,来估计文档有多么易变。
使用HTTP-EQUIV来控制HTML缓存
局限性:只支持HTML,不支持很多其他的文件类型,很少有Web服务器和代理支持此特性。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。