WEB 缓存机制

缓存,就是复用一些更新不是很频繁的网络资源,以此来减少请求数量,或者是减少带宽占用,提升服务器响应时间。

分类

  • 私有缓存
    (浏览器缓存)
  • 公有缓存
    (缓存代理服务器(cdn)或代理缓存)

优点

  • 减少冗余的数据传输,节省流量
  • 缓解带宽瓶颈问题
  • 缓解瞬间拥塞,降低对原始 server 的要求
  • 降低了距离延时(因为离服务器较远地方的客户端加载页面较慢)

处理流程

下面是一个简化版的 web 缓存处理流程。

web缓存处理流程

下面将对处理流程的细节进行讲解。

新鲜度检测

新鲜度检测,就是根据一个“保质期”来判断一个缓存是否在有效期中。

那么这个“保质期”是什么?怎么来的?

简单来讲,其实它就是 HTTP 通过缓存机制,将服务器资源的副本在客户端保留的时间。在这个有效期内,浏览器可以重复使用这个缓存资源;反之,就将它视为过期资源,并清理掉。

下面讲讲检测相关的请求头字段:

Cache-Control

这是 HTTP 1.1 新增的字段,表示资源缓存的过期时间,其值是一个时间值(以秒为单位),是一个相对时间。

当然,CC 这个字段不只是设置一个时间而已,它还有一些属性值

属性值 解释 备注
max-age 指定缓存最大的存放时间。在这段时间内不会再向服务器请求 参数是单位为秒的正整数
public 指定响应的资源可以在公有缓存中被缓存,从而被多用户共享 默认值
private 指定响应资源只能在私有缓存中缓存 (与 public 相对)
no-cache 表示必须先与服务器确认该资源是否被更改过,再决定是否使用私有缓存 依靠 Etag & If-None-Match 来判断
no-store 表示禁止缓存,每次都会下载一个新的资源 用于机密性资源

p.s.

  1. Cache-Control 也可以在请求头中设置。在这里设置的好处是,通过设置 max-age=0 可以直接向 server 确认是否有修改。
  2. no-cache 会强制每次请求直接发送到源 server,而不经过缓存版本的验证。

Expires

HTTP 1.0 规范中的字段,同样也是表示资源缓存的过期时间。和 Cache-Control 的区别在于后者是使用相对时间,而它是使用绝对时间。

但由于可能会存在一种情况,客户端和服务端的时间可能不一致,所以缓存版本会有偏差。

服务器再验证

缓存的资源过期了,这时客户端会发送请求获取新的资源,服务器会核对对应资源是否有更改。

验证方式

HTTP 1.1: If-None-Match + ETag
第一次获取资源的请求中,响应头会返回 ETag 字段,ETag 的值是一个由服务端生成的有唯一性的 hash 值。
浏览器会把 ETag 保存下来。
在以后的请求中,会在请求头中添加 If-None-Match,值为 ETag 的值,发到服务端。服务端根据传的这个值验证资源是否过期,再根据验证结果来进行相应操作。

HTTP 1.0: If-Modified-Since + Last-Modified
这两个字段的值都是具体日期,具体的验证方式,和上面的相似。
但值得注意的是,由于比对的是资源文件的最近修改时间,有些时候,可能会对文档进行周期性的重写,或者是其他的操作(去掉注释或者测试代码等不改变功能的代码块),这会更新了最近修改时间,就会产生了不必要的响应。