赞
踩
HTTP缓存主要分为Last-Modified/Etag和Cache-Control/Expires
其中Cache-Control/Expires属于强缓存,Last-Modified/Etag属于协商(比较)缓存
服务器标记资源有效期使用的头字段是Cache-Control,里面的值max-age=30就是资源的有效时间,相当于告诉浏览器,这个页面只能缓存30秒,之后就算是过期,不能用
max-age是生存时间,时间的计算起点是响应报文的创建时刻(即Date字段,也就是离开服务器的时刻),而不是客户端收到报文的时刻,也就是说包含了在链路传输过程中所有节点所停留的时间
max-age是HTTP缓存控制最常用的属性,此外在响应报文里还可以用其他的属性来更精确地指示浏览器应该如何使用缓存:
Cache-Control头部在响应中的值:
服务器的缓存控制策略流程图:
其实不止服务器可以发Cache-Control头,浏览器也可以发Cache-Control,也就是说请求-应答的双方都可以用这个字段进行缓存控制,互相协商缓存的使用策略
Ctrl+F5的强制刷新其实是发了一个Cache-Control: no-cache,含义和max-age=0基本一样,就看后台的服务器怎么理解,通常两者的效果是相同的
Cache-Control头部在请求中的值:
Expires是以前用来控制缓存的http头,Cache-Control是新版的API,现在首选Cache-Control
因为过期标准的时间用的是本地时间,所以不靠谱,所以要使用Cache-Control代替Expires
一般会把Cache-Control和Expires都设置上,因为Expires是HTTP 1.0定义的字段,而Cache-Control是HTTP 1.1的字段,万一客户端只支持HTTP 1.0,那么Cache-Control有可能就会不工作,所以一般为了兼容会都写上
HTTP协议定义了一系列If开头的条件请求字段用来检查验证资源是否过期
条件请求最常用的是if-Modified-Since和If-None-Match这两个。需要第一次的响应报文预先提供Last-modified和ETag,然后第二次请求时就可以带上缓存里的原值,验证资源是否是最新的
如果资源没有变,服务器就回应一个304 Not Modified,表示缓存依然有效,浏览器就可以更新一下有效期,然后使用缓存即可
浏览器第一次请求一个资源的时候,服务器返回的header中会加上Last-Modify,Last-modify是一个时间标识该资源的最后修改时间
当浏览器再次请求该资源时,发送的请求头中会包含If-Modify-Since,该值为缓存之前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存
如果命中缓存,则返回http304,并且不会返回资源内容,并且不会返回Last-Modify。由于对比的服务端时间,所以客户端与服务端时间差距不会导致问题。但是有时候通过最后修改时间来判断资源是否修改还是不太准确(资源变化了最后修改时间也可以一致)。于是出现了ETag/If-None-Match
若未命中强缓存,则浏览器会将请求发送至服务器。服务器根据http头信息中的Last-Modify/If-Modify-Since或Etag/If-None-Match来判断是否命中协商缓存。如果命中,则http返回码为304,浏览器从缓存中加载资源
Etag返回的是一个校验码(entity tag)。ETag可以保证每一个资源是唯一的,资源变化都会导致ETag变化,ETag值的变更则说明资源状态已经被修改。服务器根据浏览器上发送的If-None-Match值来判断是否命中缓存
ETag是HTTP1.1中才加入的一个属性,用来帮助服务器控制Web端的缓存验证。它的原理是这样的,当浏览器请求服务器的某项资源A时, 服务器根据A算出一个哈希值(3f80f-1b6-3e1cb03b)并通过 ETag 返回给浏览器,浏览器把3f80f-1b6-3e1cb03b和A同时缓存在本地,当下次再次向服务器请求A时,会通过类似If-None-Match: “3f80f-1b6-3e1cb03b”的请求头把ETag发送给服务器,服务器再次计算A的哈希值并和浏览器返回的值做比较,如果发现A发生了变化就把A返回给浏览器(200),如果发现A没有变化就给浏览器返回一个304未修改
ETag还有强和弱之分,强ETag要求资源在字节级别必须完全相符,弱ETag在值前有个W/
标记,只要求资源在语义上没有变化,但内部可能会有部分发生了改变(例如HTML里的标签顺序调整,或者多了几个空格)
为什么有了Last-modified还需要ETag呢?
Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304
参考:
https://blog.csdn.net/w57685321/article/details/92797551
《20 | 生鲜速递:HTTP的缓存控制》:https://time.geekbang.org/column/article/106804
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。