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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值