在网络请求中,我们经常看到返回码是304,返回码显示304就表示我们请求的资源没有变化,我们可以拿着之前的缓存使用,缓存对一个页面来说是必不可少的,有时候我们需要清除缓存更新数据,有时候我们需要保留缓存用来加快页面渲染。那么缓存到底是怎么来确定需不需要更新的呢?
我们可以看到控制台中的header信息有三部分:
1、General
2、response headers
3、request headers
缓存机制可以分为两种:强缓存、协商缓存
这两种缓存机制在header信息对应的字段,强缓存是cache-control和expires字段;协商缓存是Last-Modified/If-Modified-Since和Etag/If-None-Match字段
强缓存:
当浏览器再次访问某个URL时,会先获取资源的 header
信息,判断是否命中强缓存 cache-control和expires ,如果命中,直接从缓存获取资源,包括响应的 header
信息 (请求不会和服务器通信) ,如果没有命中的话再请求资源,这就是强缓存expires: http1.0
时的规范,它的值为一个绝对时间的 GMT 格式的时间字符串,如果请求的时间在expires之前,就认为资源是旧资源,使用本地缓存就可以了;否则就认为资源过期了,需要请求新的资源才可以。
cache-control: max-age=number
, http1.1
时出现的 header
信息,主要是利用该字段的 max-age
值来进行判断,它是一个相对值,这个值其实可以理解成资源的有效期;资源在第一次的请求时间的时候会和 Cache-Control 设定的有效期,计算出一个资源过期时间,再拿这个过期时间跟当前的请求时间比较,如果请求时间在过期时间之前,就认为有效,否则认为过期。
cache-control 除了该字段外,还有下面几个比较常用的设置值:
no-cache: 不使用本地缓存。
no-store: 直接禁止游览器缓存数据。
public: 可以被所有的用户缓存,包括终端用户和 CDN
等中间代理服务器。
private: 只能被终端用户的浏览器缓存,不允许 CDN
等中继缓存服务器对其缓存。
注意:如果 cache-control 与 expires 同时存在的话,cache-control 的优先级高于 expires
协商缓存
协商缓存是指浏览器和服务器协商决定是否更新缓存,这里的协商是通过两组字段来决定的,而所谓的协商的主要原理就是:每一组字段分别有两个字段,由浏览器和服务器分别控制,两个字段根据一定规则判断浏览器需不需要更新缓存。
Last-Modified/If-Modified-Since
这两个字段都是GMT的时间格式字符串,这种协商过程是:
1、在第一次请求的时候,服务器在返回资源的时候会在response的head中添加Last-Modified 字段,用来告诉浏览器这个资源的最后修改时间。
2、浏览器如果想再次请求这个资源的话,会在head里面加上 If-Modified-Since 字段,这个字段里面的值就是上次从服务器得到的Last-Modified的值。
3、服务器在收到请求的时候,会根据 If-Modified-Since 字段的值对比服务器上的最后修改时间,如果资源时间没有变化,就返回304,且不会携带别的资源内容,而且不会更新Last-Modified 字段;如果有变化就正常返回资源,同时更新Last-Modified 字段。
4、浏览器收到304,调用缓存数据;如果浏览器收到的是新数据就会更新 Modified-Since 字段,等到下次请求的时候放到If-Modified-Since 中去。
Etag/If-None-Match
这两个字段是由服务器生成的每个资源的唯一标识字符串,只要资源有变化就这个值就会改变;跟新过程与 Last-Modified、If-Modified-Since 类似,与 Last-Modified 不一样的是,如果服务器返回304的话,仍然会把Etag返回,即使Etag内容并没有什么变化。
注意:Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,ETag一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。