一、概念基础
参考原文:https://blog.csdn.net/hiredme/article/details/73468040
http的缓存,主要存在于本地浏览器和web代理服务器中。 在这里,我们讲的是浏览器缓存。
1. 响应头ETag(Entity Tag)
Etag用来表示一个资源。在服务器返回响应时包含这个值,不同的资源response返回不一样的Etag。在下次请求相同的资源时,浏览器会在 if-None-Match中带着Etag的传给服务器,如果服务器发现Etag和上次相同,直接返回304资源未发生改变,浏览器使用缓存数据。只要资源有变化,Etag就会重新生成。
请求头if-None-Match。if-None-Match表示客户端存取的是该资源的校验值,也就是Etag
Etag是上一次加载资源时,服务器返回的response header,是对该资源的一种唯一标识,只要资源有变化,Etag就会重新生成。浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的Etag值放到request header里的If-None-Match里,服务器只需要比较客户端传来的If-None-Match跟自己服务器上该资源的ETag是否一致,就能很好地判断资源相对客户端而言是否被修改过了。如果服务器发现ETag匹配不上,那么直接以常规GET 200回包形式将新的资源(当然也包括了新的ETag)发给客户端;如果ETag是一致的,则直接返回304知会客户端直接使用本地缓存即可。
Etag和Last-Modified两者之间对比:
首先在精确度上,Etag要优于Last-Modified。Last-Modified的时间单位是秒,如果某个文件在1秒内改变了多次,那么他们的Last-Modified其实并没有体现出来修改,但是Etag每次都会改变确保了精度;如果是负载均衡的服务器,各个服务器生成的Last-Modified也有可能不一致。
第二在性能上,Etag要逊于Last-Modified,毕竟Last-Modified只需要记录时间,而Etag需要服务器通过算法来计算出一个hash值。
第三在优先级上,服务器校验优先考虑Etag
2.响应头Cache-Control
Cache_-Control主要用来控制缓存相关的东西。Cache-Control头在http 1.1中定义,取代了http1.0版本中用来定义响应缓存策略的头例如(Expires)
缓存指令主要包括:
1.public private public用来声明浏览器和web代理服务器都可以缓存. private表示仅允许浏览器缓存,代理服务器不允许缓存
2.no-cache no-cache不是指不缓存,而是指每次请求资源之前都先向服务器验证该资源是否发生改变
3.no-store 表示不缓存,即浏览器和代理服务器都不缓存。
4.max-age 表示缓存的内容在XXX秒后失效。
5.must-revalidate 使得客户端再次浏览当前页面时必须法送http头信息到服务器进行验证,然后才决定是否加载客户端本地cache
if-modified-since和last-modified的比较
浏览器在第一次访问资源时,服务器返回资源的同时,在response header中添加 Last-Modified的header,值是这个资源在服务器上的最后修改时间,浏览器接收后缓存文件和header;
Last-Modified: Fri, 22 Jul 2016 01:47:00 GMT
浏览器下一次请求这个资源,浏览器检测到有 Last-Modified这个header,于是添加If-Modified-Since这个header,值就是Last-Modified中的值;服务器再次收到这个资源请求,会根据 If-Modified-Since 中的值与服务器中这个资源的最后修改时间对比,如果没有变化,返回304和空的响应体,直接从缓存读取,如果If-Modified-Since的时间小于服务器中这个资源的最后修改时间,说明文件有更新,于是返回新的资源文件和200。
二、缓存生效的过程
参考原文:https://www.cnblogs.com/mamimi/p/6900987.html
服务器收到请求时,会在200OK中返回该资源的Last-Modified和ETag头,客户端将该资源保存在cache中,并记录这两个属性。当客户端需要发送相同的请求时,会在请求中携带If-Modified-Since和If-None-Match两个头。两个头的值分别是响应中Last-Modified和ETag头的值。服务器通过这两个头判断本地资源未发生变化,客户端不需要重新下载,返回304响应。常见流程如下图所示:
三、http的缓存机制
参考于:https://www.jianshu.com/p/54cc04190252
个人对缓存数据失效的理解:个人认为缓存数据失效并不是缓存数据在内存或者磁盘中消失,只是不提供访问,但是它还是真实存在与内存或者磁盘中。
强制缓存失效:其实就是时间超过Expires或者Cache-Control中的max-age,导致缓存数据失效。
协商缓存失效:其实就是文件发生改变,Etag发生改变。
强制缓存和协商缓存
强制缓存:不会向服务器发送请求,直接从浏览器缓存中读取资源。在chrome的控制台的network选项中,可以看到该请求返回200的状态码,并且size显示from disk cache或者 from memory cache。
from memory cache代表使用内存中的缓存,from disk cache则代表使用的是硬盘中的缓存,浏览器读取缓存的顺序为memory –> disk。在浏览器中,浏览器会在js和图片等文件解析执行后直接存入内存缓存中,那么当刷新页面时只需直接从内存缓存中读取(from memory cache);而css文件则会存入硬盘文件中,所以每次渲染页面都需要从硬盘读取缓存(from disk cache)。
缓存机制工作流程
在客户端第一次请求数据时,此时浏览器缓存中没有对应的缓存数据,需要请求服务器,服务器返回数据后,将数据存储至浏览器缓存。
第二次请求数据时存在两种情况:
1.缓存数据失效。
2.缓存数据失效。
缓存标识:个人理解为Etag的值。
协商缓存就是在强制缓存失效后(也就是缓存数据失效后),浏览器带着缓存标识向服务器发起请求有服务器根据缓存标识决定是否使用缓存的过程。主要有以下两种情况:
1.协商缓存生效,返回304和Not Modified。
2.协商缓存失效,返回200和请求结果
缓存机制的总结
强制缓存优先于协商缓存进行,若强制缓存(Expires和Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified / If-Modified-Since和Etag / If-None-Match),协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表该请求的缓存失效,返回200,重新返回资源和缓存标识,再存入浏览器缓存中;生效则返回304,继续使用缓存。
原文地址:https://www.cnblogs.com/L-C98/p/9181322.html