客户端缓存

强缓存
与强缓存主要相关的header字段有expires和cache-control:max-age=number。并且如果cache-control与expires同时存在的话,cache-control的优先级高于expires

expires:这是http1.0时的规范,它的值为一个绝对时间的GMT格式的时间字符串,如Tue May 14 2019 00:00:10 GMT,如果获取时间在expires之前,本地缓存有效,反之过期
cache-control:max-age=number:这是http1.1时出现的header信息,主要是利用该字段的max-age值来进行判断,它是一个时间相对值。资源第一次的请求时间和Cache-Control设定的有效期时间,计算出一个资源过期时间。通过这个过期时间跟当前的请求时间比较,如果请求时间在过期时间之前,本地缓存有效,反之过期。cache-control除了该字段外,还有下面几个比较常用的设置值:

1)no-cache:不使用本地缓存
2)no-store:直接禁止游览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源
3)public:可以被所有的用户缓存,包括终端用户和CDN等中间代理服务器
4)private:只能被终端用户的浏览器缓存,不允许CDN等中继缓存服务器对其缓存

协商缓存
与协商缓存相关的header字段有Last-Modified/If-Modified-Since和Etag/If-None-Match
协商缓存是由服务器来确定缓存资源是否可用的,所以客户端与服务器端要通过某种标识来进行通信,从而让服务器判断请求资源是否可以缓存访问,这主要涉及到上面两组header字段,这两组搭档都是成对出现的
即第一次请求的响应头带上某个字段(Last-Modified或者Etag),则后续请求则会带上对应的请求字段(If-Modified-Since或者If-None-Match),若响应头没有Last-Modified或者Etag字段,则请求头也不会有对应的字段

Last-Modified/If-Modified-Since:
二者的值都是GMT格式的时间字符串,具体过程:

1)浏览器第一次跟服务器请求一个资源,服务器在返回这个资源的同时,在respone的header加上Last-Modified的header,这个header表示这个资源在服务器上的最后修改时间
2)浏览器再次跟服务器请求这个资源时,在request的header上加上If-Modified-Since的header,这个header的值就是上一次请求时返回的Last-Modified的值
3)服务器再次收到资源请求时,根据浏览器传过来If-Modified-Since和资源在服务器上的最后修改时间判断资源是否有变化,如果没有变化则返回304 Not Modified,但是不会返回资源内容;如果有变化,就正常返回资源内容。当服务器返回304 Not Modified的响应时,response header中不会再添加Last-Modified的header,因为既然资源没有变化,那么Last-Modified也就不会改变,这是服务器返回304时的response header
4)浏览器收到304的响应后,就会从缓存中加载资源
5)如果协商缓存没有命中,浏览器直接从服务器加载资源时,Last-Modified的Header在重新加载的时候会被更新,下次请求时,If-Modified-Since会启用上次返回的Last-Modified值

Etag/If-None-Match:
这两个值是由服务器生成的每个资源的唯一标识字符串,当资源有变化时,这个值就会改变;其判断过程与Last-Modified/If-Modified-Since类似,与Last-Modified不一样的是,当服务器返回304 Not Modified的响应时,由于ETag重新生成过,response header中还会把这个ETag返回,即使这个ETag跟之前的没有变化

Last-Modified和Etag的区别
在描述中对于Last-Modified和Etag的使用可以说是差不多的,但是,Etag(http1.1)的出现是为了解决几个Last-Modified比较难解决的问题:

一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET
某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒)
某些服务器不能精确的得到文件的最后修改时间
这时,利用Etag能够更加准确的控制缓存,因为Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符

Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304
————————————————
版权声明:本文为CSDN博主「飞驰的地铁」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zdhanunity/java/article/details/95252746

posted @ 2020-06-15 16:10  全情海洋  阅读(208)  评论(0编辑  收藏  举报