Http-缓存

作者:聂勇 欢迎转载,请保留作者信息并说明文章来源!

HTTP缓存 / Http Cache

1、ETag

Http1.1中没有规定ETag的格式和生成方式,只要求用双引号括起来。因此可以用MD5,或者直接用文件的最后修改时间。Tomcat就采用 文件大小 + “-“ + 文件最后修改时间的毫秒数 来生成ETag。
Etag 与 If-None-Match 对应。
第一次请求时,服务端响应头中有ETag(红色下划线所示)。
图1

第二次请求时,请求头中就带有If-None-Match(红色下划线所示)。服务器判断请求头中 If-None-Match 与服务端计算的ETag是否一致,如果一致就表示没有更新,返回304,否则按第一次请求时处理。
图2

2、Last-Modified

Last-Modified与If-Modified-Since对应。
第一次请求时,响应头中带有 Last-Modified(蓝色下划线所示),格式如:Wed, 22 Jul 2009 07:08:07 GMT,是零时区的 GMT 时间。
图3

第二次请求时,请求头中就带有If-Modified-Since(蓝色下划线所示)。服务器判断请求头中If-Modified-Since与请求资源的最后修改时间是否一致,如果一致就表示资源没有更新,返回304,否则按第一次请求时处理。
图4

3、Cache-Control

Cache-Control是一个集合属性,可以包含多个子属性。

  • max-age - 以秒为单位的超时,覆盖Expires属性。
  • public - 允许保存在共享缓存中。
  • private - 只允许保存在私有缓存中。
  • no-cache - 不允许缓存。
  • no-store - 不允许缓存在持久介质中。
  • no-transform - 不允许转换存储系统。

第一次请求时,响应头中带有Cache-Control(红色下划线所示)。
图5

第二次请求时,浏览器判断Cache-Control,如果是max-age并且其值有效(在有效的缓存时间内),浏览器直接使用本地缓存,不向服务端发送请求,否则按第一次请求处理;如果是no-cache和no-store,不缓存,每次都是重新向服务端请求。
图6

说明:在firebug中,使用本地缓存时,资源名称会变成灰色。

4、Expires

第一次请求时,响应头中带有 Expires(蓝色下划线所示),格式如:Wed, 22 Jul 2009 07:08:07 GMT,是零时区的 GMT 时间。
图7

第二次请求时,浏览器判断Expires,如果Expires是有效的,浏览器直接使用本地缓存,不向服务端发送请求,否则按第一次请求处理。
图8
说明:在firebug中,使用本地缓存时,资源名称会变成灰色。

附录

1、Cache-Control和Expires对F5和Ctrl+F5无效。当按F5刷新或按Ctrl+F5强制刷新时,IE和Firefox都会忽视本地缓存,重新向服务端发起请求。

Firefox IE
刷新 F5
Cache-Control: max-age=0
刷新 F5
If-Modified-Since: Sun, 21 Nov 2004 14:35:21 GMT
If-None-Match: “14f598-916-a64a7c40”
强制刷新 Ctrl+F5
Pragma: no-cache
Cache-Control: no-cache
强制刷新 Ctrl+F5
Cache-Control: no-cache

2、在多服务器部署的架构模式下,ETag有时反而会影响性能,这和ETag的具体算法有关系。