HTTP缓存
缓存控制
Cache-Control
Cache-Control 出现于 HTTP / 1.1 用于实现缓存, 使用相对时间来实现缓存,优先级高于 Expires
响应
public:表示无论私有缓存或者共享缓存,皆可将该响应缓存private:表示该响应不能被代理服务器作为共享缓存使用。若private后指定头部,则在告诉代理服务器不能缓存指定的头部,但可缓存其他部分no-cache:告诉客户端不能直接使用缓存的响应,使用前必须在源服务器验证得到 304 返回码。如果no-cache后指定头部,则若客户端的后续请求及响应中不含有这些头则可直接使用缓存no-store:告诉所有下游节点不能对响应进行缓存max-age:告诉客户端缓存时间超出max-age秒后则缓存过期s-maxage:与max-age相似,但仅针对共享缓存,且优先级高于max-age和Expires,告诉缓存最多缓存多久no-transform:告诉代理服务器不能修改消息包体的内容must-revalidate:告诉客户端一旦缓存过期,必须向服务器验证后才可使用proxy-revalidate:与must-revalidate类似,但它仅对代理服务器的共享缓存有效
请求
-
no-cache:告诉服务器不能直接使用已有缓存作为响应返回,除非带着缓存条件到上游服务端得到 304 验证返回码才可使用现有缓存 -
no-store:告诉各代理服务器不要对该请求的响应缓存(实际有不少不遵守该规定的代理服务器) -
max-age:告诉服务器,客户端不会接受时间超出max-age的缓存 -
min-fresh:要求服务器返回至少还未超过指定时间的缓存资源(在指定时间内没有过期的缓存可以返回)告诉服务器,
Age至少经过min-fresh秒后缓存才可使用 -
max-stale:接收缓存即使过期,没指定数值怎样都会接收缓存;如果指定数值,即使过期,只要没有超过指定的时间都可以接收 -
no-transform:告诉代理服务器不要修改消息包体的内容 -
only-if-cached:告诉服务器仅能返回缓存的响应,若没有缓存则返回 504 错误码
Cache-Control 可以设置为上面的一个或多个值:
1 | Cache-Control: public, max-age=315360000 |
Expires
Expires 是 HTTP / 1.0 的表示资源过期时间的头部,它描述的是一个绝对时间,由服务器返回
Expires 受限于本地时间,如果修改了本地时间,可能会造成缓存失效
1 | Expires: Wed, 11 May 2021 07:20:00 GMT |
Pragma
HTTP / 1.0 的头部,当该消息头出现在请求中时,是向服务器表达:不要考虑任何缓存,给我一个正常的结果
相当于 HTTP / 1.1 请求头中的 Cache-Control: no-cache
在Chrome浏览器中调试时,如果勾选了Disable cache,则发送的请求中会附带该信息
1 | Cache-Control: no-cache |
Vary
服务器告诉缓存服务器/客户端,只有请求持有和该头部指定的值相同且头部的相同才可以使用缓存
1 | // 浏览器 -> 代理 |

时间
Age:表示自源服务器发出响应(或者验证过期缓存),到使用缓存的响应发出时经过的秒数,代理服务器添加
1 | Age: 3825683 |
Date:表示消息发送的时间,缓存在评估响应的新鲜度时要用到
1 | Date: Wed, 11 May 2021 07:20:00 GMT |
条件
ETag
资源的实体标识,服务器会为每一份资源分配对应的 ETag 值,资源更新时,ETag 也需要更新
-
强
ETag不论实体发生多么细微的变化该值都会变化,如:
ETag: "usagi-1234" -
弱
ETag只用于提示资源是否相同,只有资源发生了根本的改变,才会改变该值,会在字段开始添加
W/如:ETag: W/"usagi-1234"
1 | ETag: W/"121-171ca289ebf" |
If-Match
它会告知服务器匹配资源所用的实体标记(ETag)值,服务器会比对 If-Match 的字段值和资源的 ETage 值,一致则会执行请求,不一致返回 412
1 | If-Match: "123456" |
If-None-Match 和 If-Match 相反,当和 ETag 值不一致时处理请求
If-Modified-Since
如果在该字段的日期之后资源没有更新,服务器返回 304,否则返回 200 + Last-Modified
1 | If-Modified-Since: Thu, 15 Apr 2004 00:00:00 GMT |
If-Unmodified-Since 和 If-Unmodified-Since 相反,如果发生了更新返回 412,没更新处理请求
目前的很多服务器,只要发现 If-None-Match 存在,就不会去看 If-Modified-Since
If-Modified-Since是http1.0版本的规范,If-None-Match是http1.1的规范
缓存原理
缓存指令
服务器在响应头中加入一些头部,可以使得浏览器进行缓存,就像这样的头部:
1 | Cache-Control: max-age=3600 |
浏览器把这次请求得到的响应体缓存到本地文件中,并标记这次请求的相关信息(请求方法、路径、缓存时间等)。

缓存判断
浏览器在加载资源时,根据请求头的 expires 和 cache-control 判断缓存是否可用:
- 可用直接从缓存读取资源,不会发请求到服务器
- 如果没有命中缓存,浏览器会发送一个带缓存的请求到服务器
- 服务器会返回缓存是否有效以及新资源
- 缓存有效:
304 Not Modified - 缓存过期:新的缓存指令 + 新的消息体
- 缓存有效:

缓存时间
浏览器会根据服务器不同的响应情况,设置不同的有效期:

强缓存和协商缓存
强缓存
强缓存通过 Expires 和 Cache-Control 两种响应头实现,也就是强缓存由服务器主动设置。
协商缓存
当浏览器对某个资源的请求没有命中强缓存,就会发一个请求到服务器,验证协商缓存是否命中,如果协商缓存命中,请求响应返回的 http 状态为 304 并且会显示一个 Not Modified 的字符串。
所谓协商缓存就是浏览器和服务器协商缓存是否有效。








