当浏览器访问服务器端,服务器给予响应时,服务器会根据需求/场景在响应头里告知浏览器,将以下数据缓存下来:
- 把这次请求得到的响应体缓存到本地文件中
- 标记这次请求的请求方法和请求路径
- 根据服务器返回值,标记缓存(过期)时间
- 记录服务器这次响应时间,格式为格林威治时间
- 标记录服务器给予的资源编号
- 标记录资源的上一次修改时间,格式为格林威治时间
当浏览器再次请求时,会优先去缓存里查找,有没有命中的缓存,没有的话,即立即请求。如果有,则判断缓存资源是否过期,这就带来了强缓存和协商缓存。
- 强缓存
如果上一次的请求资源还有效,则直接使用缓存资源,不再向服务器进行请求,主要取决于两个字段,Expires和Cache-Control中的max-age字段。一般设置其中任意一个字段都可实现强缓存策略,当两个字段同时存在时,max-age优先级会高于Expires。如果命中了强缓存,浏览器控制台的http状态码仍旧是200。
相比之下,Expires不如Cache-COntrol准确,因为Expires是截止到xxxx-xx-xx xx:xx:xx失效,无法保证浏览器和服务器的时间是同步的,所以相对不准确。而Cache-Control是有效期是xxxxms。
这里有两个概念容易混淆:
no-store:不使用任何缓存策略,每次都向服务器端请求数据
no-cache:优先和服务器确认有没有资源更新。可以理解为,没有强缓存,但是会有协商缓存
- 协商缓存
如果设置了no-cache,以及max-age(max-age=0为立即过期)过期了,这么着就命中了协商缓存,此时浏览器向服务器端请求,服务器端返回304,即缓存有效,使用缓存数据;如果返回200,即缓存失效,使用服务器端最新数据
除此之外,两者还有以下一些区别:
- 强缓存其实更多的发生在浏览器端,而 协商缓存更多的在服务器端
- 在浏览器强制刷新的情况下,强缓存不会生效,但是协商缓存不受影响
补充一下其他细节
Cache-Control:缓存时间,值有:no-store、no-cache、private、public、max-age等
Expires:这是http1.0版本,过期时间点,值如:Thu, 30 Apr 2020 23:38:38 GMT,http1.1版本更改为Cache-Control中的max-age来表示
Pragma:告知服务器,不使用任何缓存。在http1.1种,如果cache-control:no-cache也是同样的道理,以及Chrome调试中,勾选了Disable cache也是同样的效果