转自:https://www.cnblogs.com/ranyonsue/p/8918908.html
1.概览
Web 缓存大致可以分为:数据库缓存、服务器端缓存(代理服务器缓存、CDN 缓存)、浏览器缓存。
浏览器缓存也包含很多内容: HTTP 缓存、indexDB、cookie、localstorage 等等。这里我们只讨论 HTTP 缓存相关内容。
浏览器缓存主要是 HTTP 协议定义的缓存机制。
2.缓存过期机制
- 缓存命中率:从缓存中得到数据的请求数与所有请求数的比率。理想状态是越高越好。
- 过期内容:超过设置的有效时间,被标记为“陈旧”的内容。通常过期内容不能用于回复客户端的请求,必须重新向源服务器请求新的内容或者验证缓存的内容是否仍然准备。
- 验证:验证缓存中的过期内容是否仍然有效,验证通过的话刷新过期时间。
- 失效:失效就是把内容从缓存中移除。当内容发生改变时就必须移除失效的内容。
加载页面流程:
- 浏览器先根据这个资源的http头信息来判断是否命中强缓存。如果命中则直接加在缓存中的资源,并不会将请求发送到服务器,返回码200。
- 如果未命中强缓存,则浏览器会将资源加载请求发送到服务器。服务器来判断浏览器本地缓存是否失效。若可以使用,则服务器并不会返回资源信息,浏览器继续从缓存加载资源,服务器返回304重定向到浏览器缓存。
- 如果未命中协商缓存,则服务器会将完整的资源返回给浏览器,浏览器加载新资源,并更新缓存,返回200。
首次请求:
浏览器再次请求时:
强缓存可以认为没有过期的缓存,协调缓存指已过期但未被服务器修改的内容。
3.强缓存
命中强缓存时,浏览器并不会将请求发送给服务器。在Chrome的开发者工具中看到http的返回码是200,但是在Size列会显示为(from cache)。
强缓存是利用http的返回头中的Expires或者Cache-Control两个字段来控制的,用来表示资源的缓存时间。
3.1 Expires 绝对时间
缓存过期时间,用来指定资源到期的时间,是服务器端的具体的时间点。
Expires是Web服务器响应消息头字段,代表资源的失效时间,是绝对是时间。
由于失效时间是一个绝对时间,所以当客户端本地时间被修改以后,服务器与客户端时间偏差变大以后,就会导致缓存混乱。所以出现了3.2 Cache-Control
3.2 Cache-Control选项指定相对时间
https://blog.csdn.net/u012375924/article/details/82806617,讲的不错。
请求中Cache-Control可选项:
在响应中使用Cache-Control 时,它可选的值有:
Cache-Control是一个相对时间,例如Cache-Control:3600,代表着资源的有效期是3600秒。
Cache-Control比Expires优先级高。
4.协商缓存
若未命中强缓存,则浏览器会将请求发送至服务器。服务器根据http头信息中的Last-Modify/If-Modify-Since或Etag/If-None-Match来判断是否命中协商缓存。如果命中,则http返回码为304,浏览器从缓存中加载资源。
4.1 Last-Modify/If-Modify-Since
浏览器第一次请求一个资源的时候,服务器返回的header中会加上Last-Modify,Last-modify是一个时间标识该资源的最后修改时间:
当浏览器再次请求该资源时,发送的请求头中会包含If-Modify-Since,该值为缓存之前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存。
如果命中缓存,则返回http304,并且不会返回资源内容,并且不会返回Last-Modify。由于对比的服务端时间,所以客户端与服务端时间差距不会导致问题。
既然有这个为什么还有4.2 ETag呢?
1. Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间;
2. 如果某些文件会被定期生成,修改时间变了,但内容没变,但Last-Modified却改变了,导致文件没法使用缓存;
3.有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形。
4.2 ETag/If-None-Match
Etag/If-None-Match返回的是一个校验码(ETag: entity tag)。ETag可以保证每一个资源是唯一的,资源变化都会导致ETag变化*。ETag值的变更则说明资源状态已经被修改。服务器根据浏览器上发送的If-None-Match值来判断是否命中缓存。
5.总结
https://blog.csdn.net/u012375924/article/details/82806617
- 缓存开关是: pragma, cache-control。
- 缓存校验有:Expires,Last-Modified,etag。
从状态码的角度来看,它们的关系如下图:
总结:304就是在过期的但没有失效的情况下,协助缓存的结果。