通过HTTP Header控制缓存


通过HTTP Header控制缓存

文章插图
 
我们经常通过缓存技术来加快网站的访问速度,从而提升用户体验 。HTTP协议中也规定了一些和缓存相关的Header,来允许浏览器或共享高速缓存缓存资源 。这些Header包括:
  • Last-Modified 和 If-Modified-SinceETag 和 If-None-MatchExpiresCache-Control
  • 以上Header又可以分成两种类型:协商缓存:浏览器发送验证到服务器,由服务器决定是否从缓存中读取,如 1 和 2。强缓存:浏览器验证缓存的有效性,然后决定是否从缓存中读取数据,如 3 和 4。
  • 本文将会分别介绍这四种配置的作用以及可能产生的影响 。
1、Last-Modified 和 If-Modified-Since
Last-Modified:服务器在响应请求时,告知浏览器资源的最后修改时间 。
If-Modified-Since:浏览器再次发送请求时,会通过此Header通知服务器在上次请求时所得到的资源最后修改时间 。服务器会将If-Modified-Since与被请求资源的最后修改时间进行比对 。若资源的最后修改时间晚于If-Modified-Since,表示资源已被改动,则响最新的资源,返回200状态码;若资源的最后修改时间早于或等于If-Modified-Since,表示浏览器端的资源已经是最新版本,响应304状态码,通知浏览器继续使用缓存中的资源 。
2、ETag 和 If-None-Match
ETag:服务器分配给资源的唯一标识符,资源被修改后,ETag也会随之发生变化 。
If-None-Match:浏览器再次发送请求时,会通过此Header通知服务器已缓存资源的ETag 。服务器会将If-None-Match与被请求资源的最新ETag进行比对 。若不相同,表示资源已被改动,则响应最新的资源,返回200状态码;若值相同,则直接响应304状态码,通知浏览器继续使用缓存中的资源 。
3、Expires
服务器可以通过此Header向浏览器传递一个具体的时间(格林威治格式,例如:Thu, 19 Jul 2018 07:43:05 GMT) ,来明确地宣告资源的有效期 。在资源过期之前,浏览器不再发送请求,而是直接从缓存中读取数据 。只有当资源过期之后,浏览器才会再次向服务器请求该资源 。
4、Cache-Control
服务器使用此Header来向客户端建议缓存策略,它有一下几个可选值:
  • max-age=秒:告知浏览器缓存的有效时长,在该时间内浏览器将直接从缓存中读取数据 。
  • s-maxage=秒:作用同max-age,但是只对共享高速缓存(如CDN)有效,对浏览器无效 。
  • no-cache:告知浏览器不要直接使用缓存,而是必须向服务器发送请求 。
  • no-store:告知浏览器不要缓存本次请求和响应的任何信息 。
  • public:宣告任何缓存媒介都可以缓存该响应 。
  • private:宣告该响应只允许个体客户端(如浏览器)去缓存,而不允许共享高速缓存(如CDN)去缓存 。
在上面的介绍中我们了解到浏览器会根据max-age设置的时间进行缓存 。而通过研究发现CDN也会识别源站响应头中Cache-Control属性,根据max-age设置的时间进行缓存,但是,如果源站同时设置了s-maxage和max-age,那么CDN会优先采用s-maxage 。
下面通过图例来展示一下这些可选值的效果 。
首先了解一下浏览器是怎样根据max-age进行缓存的:
通过HTTP Header控制缓存

文章插图
 
从上图不难发现,服务器在Header中返回了Cache-Control: max-age=100后,浏览器成功缓存100秒,该时间段内的请求都从直接以本地缓存来响应 。
那么,服务器在Header中返回Cache-Control:s-maxage=100时,又会对浏览器产生什么样的影响呢?
通过HTTP Header控制缓存

文章插图
 
如上图所示,浏览器没有采取任何缓存策略,这是因为s-maxage面向的是共享高速缓 。
上面这两个例子很容易理解,在现实世界中,为了加快网站响应速度,我们可能会在浏览器和服务器之间引入CDN服务 。浏览器的请求会先到达CDN,然后CDN判断是从缓存中读取数据还是回源到服务器 。接下来,让我们看看max-age和s-maxage会对CDN的缓存策略带来哪些影响 。
通过HTTP Header控制缓存

文章插图
 
可以看出CDN也会利用max-age来缓存,所以在100秒内强制刷新浏览器时,CDN会直接用缓存来响应 。
如果服务器使用了s-maxage又会如何呢?
通过HTTP Header控制缓存

文章插图
 
不难发现CDN对max-age和s-maxage采取了同样的缓存策略,但浏览器并不会根据s-maxage来进行缓存 。


推荐阅读