通常浏览器缓存策略分为两种:强缓存和协商缓存,并且缓存策略都是通过设置
HTTP Header
来实现的
强缓存
强缓存可以通过设置两种
HTTP Header
实现:Expires
和Cache-Control
。强缓存表示在缓存期间不需要请求,state code
为200
Expires
Expires: Wed, 22 Oct 2018 08:41:00 GMT
Expires
是HTTP/1
的产物,表示资源会在Wed, 22 Oct 2018 08:41:00 GMT
后过期,需要再次请求。并且Expires
受限于本地时间,如果修改了本地时间,可能会造成缓存失效。
Cache-control
Cache-control: max-age=30
Cache-Control
出现于HTTP/1.1
,优先级高于Expires
。该属性值表示资源会在30
秒后过期,需要再次请求。Cache-Control
可以在请求头或者响应头中设置,并且可以组合使用多种指令
从图中我们可以看到,我们可以将多个指令配合起来一起使用,达到多个目的。比如说我们希望资源能被缓存下来,并且是客户端和代理服务器都能缓存,还能设置缓存失效时间等
一些常见指令的作用
协商缓存
- 如果缓存过期了,就需要发起请求验证资源是否有更新。协商缓存可以通过设置两种
HTTP Header
实现:Last-Modified
和ETag
- 当浏览器发起请求验证资源时,如果资源没有做改变,那么服务端就会返回
304
状态码,并且更新浏览器缓存有效期。
Last-Modified 和 If-Modified-Since
Last-Modified
表示本地文件最后修改日期,If-Modified-Since
会将Last-Modified
的值发送给服务器,询问服务器在该日期后资源是否有更新,有更新的话就会将新的资源发送回来,否则返回304
状态码。
但是 Last-Modified
存在一些弊端:
- 如果本地打开缓存文件,即使没有对文件进行修改,但还是会造成
Last-Modified
被修改,服务端不能命中缓存导致发送相同的资源 - 因为
Last-Modified
只能以秒计时,如果在不可感知的时间内修改完成文件,那么服务端会认为资源还是命中了,不会返回正确的资源 因为以上这些弊端,所以在HTTP / 1.1
出现了ETag
ETag 和 If-None-Match
ETag
类似于文件指纹,If-None-Match
会将当前ETag
发送给服务器,询问该资源ETag
是否变动,有变动的话就将新的资源发送回来。并且ETag
优先级比Last-Modified
高。
以上就是缓存策略的所有内容了,看到这里,不知道你是否存在这样一个疑问。如果什么缓存策略都没设置,那么浏览器会怎么处理?
对于这种情况,浏览器会采用一个启发式的算法,通常会取响应头中的 Date
减去 Last-Modified
值的 10% 作为缓存时间。