缓存控制设置字段和原理
HTML Meta 标签控制缓存
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
非 HTTP 协议定义的缓存机制,上述代码只是告诉浏览器当前页面不被缓存,但只有 IE 支持,非 IE 只能识别'cache-control: no-store'。在 IE 中识别到该 meta 标签含义,并不一定会在请求字段加上 Pragma,但的确会让当前页面每次都发新请求(仅限页面,页面上的资源则不受影响)。
HTTP 头信息控制缓存
pragma
通用消息头字段,设置页面是否被缓存,为 pragma 缓存,为 no-cache 不缓存
expires
Expires 是 HTTP/1.0 控制网页缓存的字段,其值为服务器返回该请求结果缓存的到期时间,即再次发起该请求时,如果客户端的时间小于 Expires 的值时,直接使用缓存结果。
cache-control
通用消息头字段,被用于在 http 请求和响应中,通过指定指令来实现缓存机制。缓存指令是单向的,这意味着在请求中设置的指令,不一定被包含在响应中。
取值:
- public:表明响应可以被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存,即使是通常不可缓存的内容(例如,该响应没有 max-age 指令或 Expires 消息头)
- private: 表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)
- no-cache: 客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定
- no-store: 所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存
- max-age=x:缓存内容将在 x 秒后失效
Last-Modified
是一个响应首部,其中包含源头服务器认定的资源做出修改的日期及时间。
If-Modified-Since
是一个条件式请求首部,服务器只在所请求的资源在给定的日期时间之后对内容进行过修改的情况下才会将资源返回,状态码为 200 。如果请求的资源从那时起未经修改,那么返回一个不带有消息主体的 304 响应,而在 Last-Modified 首部中会带有上次修改时间。只可以用在 GET 或 HEAD 请求中。
ETag
HTTP 响应头是资源的特定版本的标识符。这可以让缓存更高效,并节省带宽,因为如果内容没有改变,Web 服务器不需要发送完整的响应
If-None-Match
是一个条件式请求首部。对于 GET 和 HEAD 请求方法来说,当且仅当服务器上没有任何资源的 ETag 属性值与这个首部中列出的相匹配的时候,服务器端会才返回所请求的资源,响应码为 200。
缓存过程分析
当浏览器向服务器发起请求时,服务器会将缓存规则放入 HTTP 响应报文的 HTTP 头中和请求结果一起返回给浏览器,控制强制缓存的字段分别是 Expires 和 Cache-Control,其中 Cache-Control 优先级比 Expires 高。
强制缓存
强制缓存就是直接向浏览器查找该请求的结果,并根据结果决定是否使用缓存。主要有三种情况
不存在该缓存和标志或缓存失效
存在该缓存和标志且未失效(HTTP code 为灰色的 200, 大小为'from memory cache' 或 'from disk cache')
存在该缓存和标识,但结果已失效,则使用协商缓存
协商缓存
协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求, 由服务器根据缓存标识决定是否使用缓存的过程。控制协商缓存的字段分别有:Last-Modified / If-Modified-Since 和 Etag / If-None-Match, 其中 Etag / If-None-Match 的优先级比 Last-Modified / If-Modified-Since 高。 主要有以下两种情况:
协商缓存生效返回 304
协商缓存失效,重新请求
总结
强制缓存优先于协商缓存进行,若强制缓存(Expires 和 Cache-Control)生效则直接使用缓存, 若不生效则进行协商缓存(Last-Modified / If-Modified-Since 和 Etag / If-None-Match), 协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,重新获取请求结果, 再存入浏览器缓存中;生效则返回 304,继续使用缓存,主要过程如下:
参考: