08月14, 2018

HTTP缓存策略

HTTP缓存作为web优化的的重要手段,对于从事web开发的小伙伴来说都是必须掌握的技能。

从功能上来看,网上有将HTTP缓存分为三个部分:

  1. 缓存存储策略
  2. 缓存过期策略
  3. 缓存对比策略

缓存存储策略

顾名思义,该策略决定是否存储响应内容,哪些响应内容应该被存储。
参与该策略的首部字段有:

  • Pragma
  • Cache-Control:Public、Private、max-age 、no-cache、no-store

其中Pragma是HTTP 1.0 提供的通用首部部首,它目前只有一个值:no-cache,表示不使用缓存。

Cache-Control是一个混合的首部部首,并不仅仅表示存储策略,也控制了缓存的过期策略。其各字段表示如下:

private:              客户端可以缓存
public:               客户端和代理服务器都可缓存(前端的同学,可以认为publicprivate是一样的)
max-age=xxx:   缓存的内容将在 xxx 秒后失效
no-cache:          需要使用对比缓存来验证缓存数据(后面介绍)
no-store:           所有内容都不会缓存,强制缓存,对比缓存都不会触发

缓存存储到本地后,并不意味着后续过程中浏览器会直接从缓存中读取该数据并使用,因为我们还无法判断缓存是否可用,也许该缓存已经过期失效了。所以接下来还需要用到缓存过期验证策略。

缓存过期策略

用于控制本地缓存什么时候过期,是否可以使用本地缓存。

Expires

缓存过期时间,HTTP1.0规范,告诉客户端缓存到期的绝对时间。这个时间来自于服务器,可能会出现服务器时间与客户端时间不一致的问题,就会出现缓存失效的问题。

Cache-Control: max-age

也是缓存过期时间,不过这个时间是相对时间,告诉客户端缓存有效时间是从当前时间起的多少秒之内。该规范来自于HTTP1.1,优先级大于Expires,所以现在一般来说Expires已经失效了。

缓存有效期内,无需向服务器发起请求,直接使用本地缓存数据即可。此时http请求将返回200(from memory cache)状态码。 缓存.png

缓存对比策略

缓存未过期的时候将使用本地缓存,那么缓存过期了呢?或者是Cache-Control: no-cache呢?这个时候就需要发起请求向服务器询问了。

对比缓存的时候需要将客户端缓存标识发送给服务器,服务器判断完成后给出304状态码或者200状态码。

当缓存对比通过时,服务器给出304状态码,告诉客户端文件没有更改,可以使用本地缓存。

如果文件对比不通过,即文件以及发生改变,那么服务器会给出200状态码,并发送新的文件内容,以及新的新的缓存标识。

缓存对比主要有两种标识:

Last-Modified / If-Modified-Since

Last-Modified:服务器响应客户端时给出,告诉客户端文件的最后修改时间。
响应.png

If-Modified-Since:再次请求服务器时,客户端将带上 服务器返回的最后修改时间。

服务器收到该请求头时,将与被请求资源的最后修改时间对比,若资源的修改时间大于该时间,说明该资源被修改过,则返回200状态码并返回新的文件内容与新的文件修改时间,否则返回304状态码。

请求.png

  • 有些服务器无法得到精确的文件修改时间,这样会导致服务器无法判断缓存或者判断失误。
  • 有些时候可能出现文件内容没变,但是修改时间发生改变的情况。
  • 做负载均衡的时候,可能出现不一致的问题。

Etag/If-None-Match

与Last-Modified / If-Modified-Since类似,不过Etag/If-None-Match使用的不是文件的修改时间,而是文件的hash标识。

当第一次访问服务器时,服务器给出文件的标识为xxx,之后的请求会通过If-None-Match带上这个标识给到服务器,服务器收到该标识后与对应资源最对比,通过给出304,否则给出200并给出新的资源文件。

Etag/If-None-Match属于强验证,优先级大于Last-Modified / If-Modified-Since。另外Etag需要消耗服务器资源进行资源计算标识。如果是频繁使用的资源就最好不要使用Etag了,使用修改时间完全可以满足了。

本文链接:https://luodao.me/post/http-huancun.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。