Skip to content

HTTP缓存

TIP

浏览器在发起HTTP请求时,会对请求的静态文件进行缓存,缓存主要分为两种:强缓存、协商缓存。

缓存规则

在浏览器第一次请求数据时,缓存中没有对应的缓存数据,需要请求服务器,服务器返回后,将数据存储在缓存中。第一次请求

在后续请求时,则根据是否需要向服务器重新发起HTTP请求将缓存过程分为强缓存和协商缓存两部分。

强缓存(优先级高于协商缓存)

相关Response Header

Expire

Expires: Tue, 01 Oct 2030 00:58:41 GMT,Expires是HTTP/1.0控制缓存的字段,值为服务端返回的到期时间;如果下一次请求时请求时间小于服务端返回的到期时间,直接使用缓存数据。

到了HTTP/1.1,Expires已经被Cache-Control替代;由于Expires控制缓存的原理是使用客户端的时间与服务端返回的时间做对比,如果客户端与服务端的时间由于某些原因(时区不同;客户端和服务端有一方的时间不准确)发生误差,那么强缓存会直接失效。

Cache-Control

HTTP/1.1中,Cache-Control 是控制缓存最重要的规则;其常见取值如下:

  • public:所有内容都将被缓存(客户端和代理服务器都可缓存)
  • private:所有内容只有客户端可以缓存,Cache-Control的默认取值
  • max-age=xxx:缓存内容将在xxx秒后失效
  • no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定
  • no-store:所有内容都不会被缓存,即不使用强缓存也不使用协商缓存

tip: 当两者同时存在时,Cache-Control优先级高于Expires。

协商缓存

相关header

Last-Modified/If-Modified-Since

TIP

Last-Modified是服务器在响应请求时,告诉浏览器资源的最后修改时间,在response header里返回;同时浏览器会将这个值保存起来,再次发起请求时会将If-Modified-Since在request header里带上。

服务器收到请求后发现有If-Modified-Since,则与被请求资源的最后修改时间进行对比:

  • 若资源的最后修改时间大于If-Modified-Since,说明资源被改动,则响应全部资源内容,返回状态码200。
  • 若资源的最后修改时间小于或等于If-Modified-Since,说明资源没有被修改,则返回状态码304(不会响应资源内容),告知浏览器继续使用缓存。

缺点:

  • 负载均衡的服务器,各个服务器生成的Last-Modified可能有所不同
  • GMT 格式有最小单位,如果在一秒内资源有更改将不能被识别

ETag/If-None-Match(优先级高于 Last-Modified/If-Modified-Since)

TIP

Etag是服务器响应请求时,返回当前资源文件的一个唯一标识序列,当资源有变化时,Etag就会重新生成; If-None-Match是浏览器再次发起请求时会带上的请求头。

服务器收到请求后的具体流程与Last-Modified/If-Modified-Since类似

缺点:

  • ETag的生成需要消耗一定时间,效率不及前一种方法

用户行为对缓存的影响

  • F5刷新:浏览器会设置max-age=0,跳过强缓存判断,会直接进行协商缓存判断。
  • ctrl+F5强制刷新:跳过强缓存和协商缓存,直接从服务器拉取资源。

总结

  • 强缓存优先于协商缓存进行,若强缓存生效则直接使用缓存,若不生效则进行协商缓存。

  • 协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,重新获取请求结果,再存入浏览器缓存中;生效则返回304,继续使用缓存。

  • 浏览器再次发起请求时:

浏览器再次发起请求时

Updated at: