HTTP中缓存相关的字段(Cache-Control, Expires, Last-Modified, ETag)介绍 以及浏览器前进后退行为的缓存特点

我们都知道浏览器会尝试缓存资源,以便下次需要的时候从本地缓存中获取资源,减少向服务端获取资源的时间
HTTP协议中关于缓存主要有Cache-Control, Expires, Last-Modified, ETag几个字段,容易混淆,本文结合个人经验分别介绍其特点,不具体介绍如何配置


 

  

 
Expires

  (HTTP/1.0)服务端生成,表示资源过期的日期(未来的某个固定时间)
 

  示例:Expires: Thu, 15 Feb 2018 08:10:23 GMT
 

  该字段同Cache-control中的max-age的效果。但是如果同时存在,则被Cache-Control的max-age覆盖。若把其值设置为0,则表示页面立即过期。
 

 效果:
 浏览器第一次请求资源,会保存Expires数据,下次再次请求该资源的时候,先判断,如果为未过期,则不会向服务端发送请求,直接从缓存中获取(from disk cache)

Cache-control (http://www.jb51.net/article/34017.htm)
(HTTP/1.1)服务端生成


 示例:
Cache-Control:max-age=2592000(表示资源将在x秒数之后过期)

Cache-Control:no-cache

Cache-Control:no-store 

Cache-Control: private

效果:


 max-age 效果与Expires类似,指的是从文档被访问后的存活时间,这个时间是个相对值(比如:3600s),相对的是文档第一次被请求时服务器记录的Request_time(请求时间)
no-cache,no-store表示资源不在客户端缓存


Pragma

 与Cache-Control相同。但是是为了兼容http 1.0 的。比如Pragma: no-cache兼容http 1.0 

 Cache-Control: no-cache是http 1.1提供的。这样就保证了不支持http 1.1的浏览器可以正常使用缓存功能。

Last-Modified

 表示资源的修改时间(服务端时间)

 示例:Last-Modified: Tue, 06 Jun 2017 06:04:45 GMT

 效果:浏览器会缓存资源的Last-Modified值,以后再次发送资源请求的时候,浏览器会在请求头中添加If-Modified-Since
 字段(即上次缓存的Last-Modified值),服务端比较If-Modified-Since的值和资源的实际修改时间,如果未修改,则返回304,不返回资源的实际内容,表示资源未改动,则浏览器使用缓存中的资源

 问题:

 1、周期性更改的文件且内容并不改变会导致缓存判断失败(比如文件覆盖,仅仅改变修改时间)。

 2、有些文件修改极其频繁,也许1秒内修改了很多次,If-Modified-Since能检查到的最小单位是秒级的,所以这种修改无法判断

 3、在集群服务器上各个服务器上的文件时间可能不同

ETag

 (EntityTags,HTTP1.1之后出现)表示被请求的实体的token或hash,主要解决Last-Modefied的问题,服务端生成,

 示例:ETag:W/"593645fd-19baa"

 效果:客户端请求的时候会发送If-Match或者If-None-Match(即缓存的ETag值),服务端判断If-None-Match值来验证资源是否修改,如果未修改,则返回304

 If-None-Match是从客户端发送过去的字段,值是这个资源的Etag值

以上特性对于浏览器的常规访问生效,但是浏览器的前进后退行为较为特殊


 关于前进后退行为的实验:

 把Expires和Cache-Control都设置成0,

 Chrome: 前进后退的时候是from disk cache,在地址栏回车、点击链接打开、window.open打开页面都是304(如果页面是iframe,效果是一样的)

 IE: 前进后退的时候是304,在地址栏回车、点击链接打开、window.open打开页面都是304。前进后退的时候,用Fiddler抓包发现没有捕捉到这个请求,所以实际上前进后退的时候,IE和Chrome的现象是一样的(from disk cache)

 关于前进后退行为:

 (History mechanisms and caches are different. In particular history mechanisms SHOULD NOT try to show a semantically transparent view of the current state of a resource. Rather, a history mechanism is meant to show exactly what the user saw at the time when the resource was retrieved. https://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html)

 即,前进后退行为总是尽量重现之前的场景,而不会遵照浏览器的缓存策略

 想要前进后退时资源不从缓存读取,唯一的方法是把html资源设置成no-cache:
html资源:设置成no-cache,前进后退不会读缓存

html中的js资源:即使设置成no-cache,前进后退的时候,结果也是from disk cache


 

总结:

现代前端开发,都会用webpack或者gulp等工具实现工程化打包,所以js、css等资源名都会带有hash后缀,一旦资源修改,对应的资源名也会随之改变。所以在配置服务器的时候,可以把Expires、max-age字段设置得足够长,充分利用浏览器的缓存。

但是html资源除外,由于在前进后退的时候,html资源默认都会使用上一次的资源,如果在前进、后退期间服务端更新了资源,若想要新资源立即生效,可以把html资源设置成no-cache
————————————————
版权声明:本文为CSDN博主「tzy233」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/tzy233/article/details/79311945

你可能感兴趣的:(chrome,http,缓存,java)