若最后修改时间小于等于If-Modified-Since,则response header返回304,告知浏览器继续使用所保存的cache。若大于If-Modified-Since,则说明资源被改动过,返回状态码200;
2. If-none-match / Etag
Etag:服务器响应请求时,告诉浏览器当前资源在浏览器的唯一标识(生成规则由服务器确定)
If-None-Match:再次请求服务器时,通过此字段通知服务器客户端缓存数据的唯一标识。服务器收到请求后发现有If-None-Match 则与被请求资源的唯一标识进行比对,不同,说明资源又被改动过,则响应整片资源内容,返回状态码200;相同,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用所保存的cache。
Etag与Last-Modified对比:
1.在精确度上,Etag优于Last-Modified。Last-Modified精确到s,如果1s内,资源多次改变,Etag是可以判断出来并返回最新的资源。
2.在性能上,Last-Modified优于Etag,因为Last-Modified只需要记录时间,而Etag需要服务器重新生成hash值,所以性能上略差。
3.在优先级上,Etag优于Last-Modified,Etag和Last-Modified可同时存在。本地缓存时间到期后,浏览器向服务端发送请求报文,其中Request Header中包含If-none-match和Last-Modified-Since(与服务端Etag和Last-Modified对比,Etag优先级高),用以验证本地缓存数据验证是否与服务端保持一致。在服务器端会优先判断Etag。如果相同,返回304;如果不同,就继续比较Last-Modified,然后决定是否返回新的资源。若服务端验证本地缓存与服务端一致,返回304,浏览器加载本地缓存;否则,服务器返回请求的资源,同时给出新的Etag以及Last-Modified时间。
3.3 缓存请求以下为浏览器缓存的流程:
4 实例分析对于客户端来说,浏览器在使用本地缓存数据时,需要对齐本地与服务器的资源;但是,对于服务端,服务器将资源下发给客户端,服务端就失去了对齐的控制权。比如,服务端设定缓存失效的max-age,在这段时间内,哪怕服务端资源已发生更改,服务端也无法通知客户端资源更新通知。所以,对于一个网页来说,需要合理的指定缓存的废弃与更新的响应策略,从而既能提升页面加载速度,同时确保页面的准确性。
以下结合华为云官网各部件,分析缓存的废弃和更新的响应策略:
4.1 官网首页:注释:
Html:缓存有效时间为0s,页面加载时,强制浏览器每次向源服务器确认数据;
Css:改动频率较低,允许使用本地缓存,且存在强制缓存时间(各个css文件不同,按需设置);强制缓存失效再进行协商缓存;
Js:允许使用本地缓存,且存在强制缓存时间(各个js文件不同,按需设置);强制缓存失效再进行协商缓存;
Image:图片修改频率更低,允许使用本地缓存,且存在强制缓存时间(各个image文件不同,按需设置);强制缓存失效再进行协商缓存;
Gif:官网中gif主要存在于banner轮播,因此确保时效性,使用no-cache,不允许缓存,强制每次向源服务器确认数据。
注意(以下已官网首页为例,介绍缓存与版本号的关系,其余各部件都存在相同问题,后续不一一解释。):
上图描述的是可缓存文件的缓存策略。但是,网页中还有很多文件,比如global.js、global.css等,更新频率较快,如果一直使用本地缓存可能会影响页面的正确性。因此,在引用这部分文件时,会在文件后添加个版本号,用以刷新缓存,以此确保本地资源的时效性,添加版本号的目的是为了强制要求文件每次加载重新向服务端请求。如下,左图给出了部分文件的版本号后缀。这部分文件在浏览器重新加载后,请求报文的头文件,Request Header的Cache-control值为no-cache,即无缓存,重新请求数据。如下右图所示:
4.2 社区注释: