1

『图解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=0no-cache的区别?
返回的状态来看:no-cache都是200,而max-age可能是304(如果浏览器有缓存)。
请求参数:max-age请求头一般会携带If-Modified-SinceIf-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服务器和代理支持此特性。


哈鲁
1.2k 声望25 粉丝

前端开发