HTTP缓存机制
文章目录
缓存是一种保存资源副本并在下次请求时直接使用该副本的技术.
Web 缓存能够减少延迟与网络阻塞,进而减少显示某个资源所用的时间。借助 HTTP 缓存,Web 站点变得更具有响应性。
缓存技术有: 网关缓存、CDN、方向代理缓存、负载均衡器等部署在服务器端的缓存技术.
HTTP缓存是浏览器和服务器协同工作完成的一种机制.它可以帮助Web应用更开始的响应用户的行为.
而在HTTP缓存中只能存储GET请求的响应,对于其他类型的响应无能为力.
HTTP的缓存策略通过在请求头中做一些设定完成的.
HTTP缓存方式分为强制缓存和协商缓存
强制缓存
强制缓存, 如果浏览器发现请求资源的日期未过期则直接取本地缓存的副本. 不向服务器发起请求.
Expires
Expires
响应头包含日期/时间, 即在此时候之后,响应过期。
无效的日期,比如 0, 代表着过去的日期,即该资源已经过期。
如果在Cache-Control
响应头设置了 “max-age” 或者 “s-max-age” 指令,那么 Expires
头会被忽略。
1 | Expires: <http-date> |
Cache-Control: mx-age/s-max-age
Cahce-Control
的配置指令有很多种,和强制缓存相关的指令有 mx-age
和s-max=age
mx-age
Cache-Control: max-age=<seconds>
设置缓存存储的最大周期,超过这个时间缓存被认为过期(单位秒)。与Expires
相反,时间是相对于请求的时间。
s-max-age
s-maxage=<seconds>
覆盖max-age
或者Expires
头,但是仅适用于共享缓存(比如各个代理),私有缓存会忽略它。
协商缓存
协商缓存,浏览器会向服务器发送请求用来验证本地资源是否过期,服务器会校验客户端资源是否过期,如果未过期则返回304,响应不包含body.否则服务器返回200并且响应体包含body.
ETag/If-None-Match
ETag
HTTP响应头是资源的特定版本的标识符。如果给定URL中的资源更改,则一定要生成新的Etag值。 因此Etags类似于指纹,也可能被某些服务器用于跟踪。 比较etags能快速确定此资源是否变化,但也可能被跟踪服务器永久存留。
浏览器在第一次请求资源时.服务器会将资源反回,并将ETag=xxxxx
一起返回个浏览器,浏览器在第二次请求相同资源时候,在请求头部设定if-None-Match=ETag的值
.
服务器会拿资源最新的ETag值和浏览器传的if-None-Match做对比,如果一样则返回304,否则返回最新的资源和最新ETag值.
Last-Modified/If-Modified-Since
The Last-Modified
是一个响应首部,其中包含源头服务器认定的资源做出修改的日期及时间。 它通常被用作一个验证器来判断接收到的或者存储的资源是否彼此一致。由于精确度比 ETag
要低,所以这是一个备用机制。包含有 If-Modified-Since
或 If-Unmodified-Since
首部的条件请求会使用这个字段。
If-Modified-Since
是一个条件式请求首部,服务器只在所请求的资源在给定的日期时间之后对内容进行过修改的情况下才会将资源返回,状态码为 200
。如果请求的资源从那时起未经修改,那么返回一个不带有消息主体的 304
响应,而在 Last-Modified
首部中会带有上次修改时间。 不同于 If-Unmodified-Since
, If-Modified-Since
只可以用在 GET
或 HEAD
请求中。
当与 If-None-Match
一同出现时,它(**If-Modified-Since
**)会被忽略掉,除非服务器不支持 If-None-Match
。
缓存策略
除了/定缓存是否过期方式外, 还可以设定缓存的策略
Cache-Control
Cache-Control
通用消息头字段,被用于在http请求和响应中,通过指定指令来实现缓存机制。缓存指令是单向的,这意味着在请求中设置的指令,不一定被包含在响应中。
指令不区分大小写,并且具有可选参数,可以用令牌或者带引号的字符串语法。多个指令以逗号分隔。
1 | max-age:用来设置资源(representations)可以被缓存多长时间,单位为秒; |
Vary
Vary
是一个HTTP响应头部信息,它决定了对于未来的一个请求头,应该用一个缓存的回复(response)还是向源服务器请求一个新的回复。它被服务器用来表明在 content negotiation algorithm(内容协商算法)中选择一个资源代表的时候应该使用哪些头部信息(headers).
1 | Vary: * |
参考
作者: Fynn
链接: https://fynn90.github.io/2019/05/23/Http%E7%BC%93%E5%AD%98%E6%9C%BA%E5%88%B6/
本文采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可