HTTP 协议中缓存处理机制(Expires、Last-Modified、ETag

 

应用场景

了解 HTTP(我们这里说的是 HTTP/1.1) 协议中缓存的处理机制,会对网站优化有些许帮助,例如会应用到:加速网站的加载,服务器端与浏览器文件及时同步。

浏览器请求 URL 时,根据 HTTP 协议的规定,浏览器与服务器会通过报头(HTTP Request HeaderHTTP Reponse Header)进行交流,并根据其协议中和缓存的相关字段(Expires、Last-Modified、ETag)进行处理缓存。参数示例如下:

  • Expires: 12:07:08 Monday, May 20, 2013 GMT
  • Last Modification: 03:21:32 Wednesday, November 21, 2012 GMT
  • Last Cache Update: 12:07:08 Wednesday, November 21, 2012 GMT
  • Last Access: 14:33:07 Tuesday, November 27, 2012
  • ETag: “3511605509″

缓存处理流程

1.浏览器第一次请求 URL,若此资源正常服务器将返回状态 200,并获取存储与缓存相关的属性,用于以后的请求:

  • Expires: 记录超时时间,即文件到了这个记录的时间点,就不能再用浏览器的对应此 URL 的缓存了,该去服务器上拿了。
  • Last Modification: 服务器中,此 URL 对应文件在服务器的最近更新时间。
  • ETag: “被请求变量的实体标记”,可以理解为服务器中此 URL 对应文件的唯一标识符。

2.浏览器第二次请求 URL,首先将比较 Expires 的时间与当前请求时间,若未超时,则直接读取缓存,不与服务器交互。

3.若比较 Expires 发现已超时或缓存失效时,浏览器将请求 URL。同时带了属性,用于检测文件是否更新:

  • If-None-Match: 值为第一次请求的 ETag。
  • If-Modified-Since: 值为第一次请求的 Last-Modification。

4.若 If-None-Match 值(即 ETag)未改变,且 If-Modified-Since 该时间之后文件未被修改过,则服务器仅返回状态 304,意思就是,不用更新,从缓存中拿吧~ 这样做的好处是,不用重复传输文件内容了,提高了加载速度又确定了文件与服务器一致,另外,也重新计算 Expires 的值(若超时时间为 24h,则 Expires 值刷新为此请求时间的一天后)。

5.若 If-None-Match 值改变,或比较 If-Modified-Since 时间发现文件被修改,则文件已更新,服务器将重新发出资源,返回和第一次请求流程类似。

流程结束。这样的流程好处是:既保证不向浏览器重复发送同一资源,有保证了当服务器 URL 对应资源有更新时,客户端能够同步到最新的资源。

应用实例

在实际的网站开发中,线上环境通常会有出现 CSS、JS 更新,若服务器端已更新,而浏览器还是在使用缓存而不同步,将出现页面展示或 JS 异常等问题,为了保证浏览器能及时同步资源,我们可以这样做:

将 Expires 设置为 -1,意思是立即超时,则每次加载资源都会请求 URL,通过 Last Modification 和 ETag 来由服务器来判断是否更新。这样就保证了服务器与浏览器资源文件同步。

上面的方法虽然同步了,但是也使所有资源文件每次都将访问服务器,而建立连接,本来就会有时间损耗,所以改进如下:

将 Expires 设为一年或者更长 ,则浏览器不会主动请求 URL。但在 URL 后面加上类似时间戳的参数,例如 “website/css/index.css?tm=2012112730.css”,后面跟的参数其实是没有实际意义的,但是,每次在我们需要客户端同步对应文件时,仅需要修改对应文件 URL 的 tm 参数即可,浏览器发现 URL 为新 URL,将即刻更新。

百度、淘宝等对 JS、CSS缓存处理用的基本都是上面的策略,这样做的好处是:浏览器默认任何时候都仅使用缓存,加快了加载。而当文件需要更新时,通过修改参数又能让浏览器及时更新。

总结

了解协议对优化和规范网站开发有不少帮助,上面提到的属性和应用场景容易被开发者疏忽,在现在这种互联网开发迭代速度极快的节奏下,上面的问题就会更加容易暴露,规范处理好了会省心很多。

本文提到的属性和应用场景是协议和网站开发的一小部分,抛砖引玉,欢迎纠错

猜你喜欢

转载自chunguang.iteye.com/blog/1821110