浏览器缓存机制详解

对于浏览器缓存,相信很多开发者对它真的是又爱又恨。 一方面极大地提升了用户体验,而另一方面有时会因为读取了缓存而展示了错误的东西,而在开发过程中千方百计地想把缓存禁掉。那么浏览器缓存究竟是个什么样的神奇玩意呢?

什么是浏览器缓存

简单来说,浏览器缓存就是把一个已经请求过的Web资源(如html, 图片, js, 数据等)拷贝一份副本在浏览器中,缓存会根据进来的请求保存输出内容的副本。当下一个请求来到的时候,如果是相同的URL,缓存会根据缓存机制决定是直接使用副本响应访问请求,还是向源服务器再次发送请求。比较常见的就是浏览器会缓存访问过的网站的网页,当再次访问这个URL地址的时候,如果网页没有更新,就不会再次下载网页,而是直接使用本地缓存的网页。只有当网站明确标识资源已经更新,浏览器才会再次下载网页。至于浏览器和网站服务器如何标识网站页面是否新更新的机制,将在下面介绍。
Alt
上图就是使用了缓存的例子,在页面请求之后,web资源都被缓存了,在后面的重复请求中,可以看到许多资源都是直接从缓存中读取的(from cache) 而不是重新向服务器请求。

为什么使用缓存

1)减少网络宽带消耗
无论对于网站运营者或者用户,带宽都代表着金钱,过多的带宽消耗,只会便宜了运营商。当Web缓存副本被使用时,只会产生极小的网络流量,可以有效的降低运营成本。
2)降低服务器压力
给网络资源设定有效期后,用户可以重复使用本地的缓存,减少对源服务器的请求,间接降低服务器的压力,同时搜索引擎的爬虫机器人也能根据过期机制降低爬取的频率,也能有效降低服务器的压力。
3)减少网络延迟,加快页面打开速度
带宽对于个人网站运营者来说是十分重要的,而于于大型的互联网公司来说,可能有时候因为钱多而真的不在乎,那么Web缓存还有作用吗?答案是肯定的,对于最终用户,缓存的使用能够明显加快页面的打开速度,达到更好的体验。

浏览器的缓存规则

对于浏览器端的缓存来讲,这些规则是在HTTP协议头和HTML页面的Meta标签中定义的。他们分别从新鲜度和校验值两个维度来规定浏览器是否要以直接使用缓存中的副本,还是需要去源服务器获取最新的版本。

新鲜度(过期机制)

也就缓存副本的有效期,一个缓存副本必须满足以下条件,浏览器才会认为它是有效的,足够新的:
1)含有完整的过期时间控制头信息(HTTP协议报头: Cache-Control),并且仍在有效期内;
2)浏览器已经使用过这个缓存副本,并且在一个会话中已经检查过新鲜度;
满足以上两个情况的一种,浏览器会直接从缓存中获取副本并渲染。

校验值(验证机制)

服务器返回资源的时候有时在控制头信息带上这个资源的实体标签Etag, 它可以用来作为浏览器再次请求过程的校验标识,如过程发现校验标识不匹配,说明资源已经被修改或过期,浏览器需要重新获取资源内容。

浏览器是如何判断缓存是否过期?

应该是根据Reponse Header里面的Cache-Control和Expires这两个属性,当两个都存在时,Cache-Control优先级较高。

浏览器缓存分为:强缓存和协商缓存
强缓存

浏览器加载资源时,第一步先判断它是否是强缓存,如果是,浏览器将直接从自己的缓存中读取,不会向服务器发送请求。
1)Expires
1.1).浏览器第一次向服务器请求,服务器返回资源并在response header加上Expires字段,是客户端缓存有效期,是绝对时间。
1.2) 浏览器接收资源,把资源和响应头缓存起来。
1.3) 待到再次请求这个资源时,先在缓存中找,找到了看Expires字段,判断是否过期,若没有过期直接从缓存加载。若过期了,再向服务器请求。
2)Cache-Control
2.1) 浏览器第一次向服务器请求,服务器返回资源并在response header加 上Cache-Control字段,也是缓存的有效期,是相对时间,比如: Cache-Control: max-age=56700000
2.2) 浏览器接收资源,把资源和响应头缓存下来
2.3) 待到浏览器再次请求这个资源时,先在缓存找,根据第一次的请求时间和Cache-Control相对时间算出过期时间。或没有过期,直接从缓存加载。若过期,再向服务器请求。

Expires: 绝对时间有时会有偏差,所以引出了Cache-Control,更安全有效

服务端如何判断缓存已失效?

服务端通过if-Modified-Since(Last-Modified)和if-None-Match(Etag)这两个属性的值来判断缓存是否失效的。

协商缓存

当浏览器判断不是强缓存,就会向服务器发送请求,判断是否是协商缓存,如果是,服务器会返回304 Not Modified,浏览器从缓存中加载,那什么又是协商缓存呢?

  1. Last-Modified 和 if-Modified-Since
    1.1) 浏览器第一次向服务器发送请求,服务器返回资源并在response header加上Last-Modified字段,表示资源最后修改的时间。
    1.2)浏览器再次请求这个资源时,请求头会加上if-Modified-Since字段,若这两个字段一样,说明资源没有修改过,返回304 Not Modified, 浏览器从缓存中获取资源,若这两个字段不一样,说明资源修改过,服务器正常返回资源 。
  2. Etag 和 if-None-Match
    但有时候服务器上资源有变化,但最后修改的时间没有更新,则引出下面两个字段。
    2.1) 浏览器第一次向服务器请求,服务器返回资源并在response header 上加Etag字段,表示资源本身,资源有变化,则该字段有变化。
    2.2) 浏览器再次向服务器请求这个资源时,请求头会加上if-None-Match字段,若两个字段相同,则代表资源没有变化,服务器返回304 Not Modified,浏览器从缓存中加载,若两个字段不同,证明资源有变动,服务器正确返回资源。

浏览器HTTP请求流程:

第一次请求:

Alt
再次请求:
Alt

用户行为与缓存:

在这里插入图片描述

不能缓存的请求:

当然并不是所有请求都能被缓存,无法被浏览器缓存的请求如下:
 1. HTTP信息头中包含Cache-Control:no-cache,pragma:no-cache(HTTP1.0),或Cache-Control:max-age=0等告诉浏览器不用缓存的请求

2. 需要根据Cookie,认证信息等决定输入内容的动态请求是不能被缓存的

3. 经过HTTPS安全加密的请求(有人也经过测试发现,ie其实在头部加入Cache-Control:max-age信息,firefox在头部加入Cache-Control:Public之后,能够对HTTPS的资源进行缓存,参考《HTTPS的七个误解》)

4. POST请求无法被缓存
 
5. HTTP响应头中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的请求无法被缓存

参考资料:

  1. http://www.cnblogs.com/520yang/articles/4807408.html 浏览器 HTTP 协议缓存机制详解

  2. https://my.oschina.net/leejun2005/blog/369148 浏览器 HTTP 协议缓存机制详解

  3. http://web.jobbole.com/82997/ 浏览器缓存机制浅析

  4. http://www.alloyteam.com/2012/03/web-cache-2-browser-cache/ Web浏览器的缓存机制

  5. http://www.cnblogs.com/vajoy/p/5341664.html 浅谈浏览器http的缓存机制

  6. http://mp.weixin.qq.com/s/yf0pWRFM7v9Ru3D9_JhGPQ 浏览器缓存机制剖析

  7. https://www.cnblogs.com/slly/p/6732749.html 浏览器缓存机制详解

  8. https://www.jianshu.com/p/77987f573bc0 html meta 标签和浏览器缓存关系

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值