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,继续使用缓存。
浏览器再次发起请求时: