浏览器 HTTP 协议缓存机制

jQuery
前几天项目里用到了一个简易的播放器进行SVG图片的播放,但是因为SVG尺寸较大,在网络环境差的情况下可能导致播放卡顿严重,这时候如果用上浏览器缓存的话,就能一定程度上(至少加载过的图片再次加载时可以秒加载)缓解这个问题。但是很奇怪的是尽管我们没有在前端和后端禁用浏览器缓存,用ajax发出的get请求在url完全相同的情况下依然没有从缓存中直接读取,找了各种资料大家似乎都说默认浏览器缓存是开启的,经过我们反复的测试静态文件都能直接缓存,但是ajax的请求却不行,后来国勇哥丢给我们一个链接:【原文地址】看完之后顿觉醍醐灌顶,终于问题得到了解决,这里在原文的基础上再次整理一下。

浏览器缓存机制

我们先来看看浏览器的缓存机制,浏览器第一次访问时:
第一次访问时

 

当浏览器第一次访问时向浏览器发送请求,然后响应请求,根据返回的Cache-Control等信息将资源缓存,然后呈现在页面上,这个时候我们应该试着了解一下Cache-Control之类的参数如何配置:

  • Expires策略:Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。不过Expires 是HTTP 1.0的东西,现在默认浏览器均默认使用HTTP 1.1,所以它的作用基本忽略。Expires 的一个缺点就是,返回的到期时间是服务器端的时间,这样存在一个问题,如果客户端的时间与服务器的时间相差很大(比如时钟不同步,或者跨时区),那么误差就很大,所以在HTTP 1.1版开始,使用Cache-Control: max-age=秒替代。
  • Cache-control策略(重点关注):Cache-Control与Expires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires。Cache-control的值通常有这些:


  • Public: 指示响应可被任何缓存区缓存。

  • Private: 指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效。
  • no-cache: 指示请求或响应消息不能缓存,该选项并不是说可以设置”不缓存“,容易望文生义~
  • no-store: 用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存,完全不存下來。
  • max-age: 指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。
  • min-fresh: 指示客户机可以接收响应时间小于当前时间加上指定时间的响应。
  • max-stale: 指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。


    除此之外还有这些参数:

  • Last-Modified:标示这个响应资源的最后修改时间。web服务器在响应请求时,告诉浏览器资源的最后修改时间。

  • Etag:web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。 什么?你问有了Last-Modified拿Etag有什么x用? Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间 如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形 Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。Last-Modified与ETag一起使用时,服务器会优先验证ETag
  • If-Modified-Since:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Last-Modified声明,则再次向web服务器请求时带上头 If-Modified-Since,表示请求时间。web服务器收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源又被改动过,则响应整片资源内容(写在响应消息包体内),HTTP 200;若最后修改时间较旧,说明资源无新修改,则响应HTTP 304 (无需包体,节省浏览),告知浏览器继续使用所保存的cache。
  • If-None-Match:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Etage声明,则再次向web服务器请求时带上头If-None-Match (Etag的值)。web服务器收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,决定返回200或304。


好了让我们来看看当浏览器第二次访问资源的时候是怎样的一个流程:
第二次访问时

 

 

最后我们来适当了解一下上图出现的几个状态码:状态码

相信这些内容已经足够用于解决浏览器缓存问题了

2015年9月29日 23:17:22

 

坚持原创技术分享,您的支持将鼓励我继续创作!