HTTP 缓存策略

当使用浏览器访问一个 Web 资源时,为了提高访问效率,往往会在浏览器和服务器之间增加本地缓存

对于首次访问,会将服务器响应的数据缓存到本地;对于后续的访问,会根据缓存策略决定是否直接使用本地缓存。简化的流程如下图所示:

1

注意:缓存策略完全是根据服务器响应消息的头信息来决定滴!!

与缓存有关的消息头字段

先给出与缓存有关的消息头字段的一些说明:

2

强制缓存

顾名思义,强制缓存不需要服务器的参与,浏览器可以自己决策是否使用缓存,决策规则如下:

在响应消息中,Expires 是根据 Last-Modified 和 max-age 计算出来的,max-age 表示存活多少秒后过期,而 Last-Modified 表示最后的修改时间

如果一个请求直接强制使用缓存,那么该请求会显示200 OK (from disk cache),如下所示:

协商缓存

顾名思义,协商缓存是浏览器和服务器共同协商是否使用本地缓存,浏览器负责提供本地缓存的信息,如:最后修改时间和唯一标识,添加在请求消息头中,服务器收到消息后来决策是否允许浏览器使用本地缓存

If-Modified-Since 和 If-None-Match 是在浏览器第一次发送请求到服务器时,从服务器的响应消息保存。如果浏览器发现本地缓存中不存在要请求的资源,会直接将请求发送到服务器

协商缓存基于两种消息头字段实现:

对于第一种,如果 If-Modified-Since 时间小于 Last-Modified,表示本地缓存中是旧数据,不可以使用本地缓存中的数据,否则可以使用缓存

对于第二种,如果 If-None-Match 和 Etag 不相等,表示本地缓存中是旧数据,不可以使用本地缓存中的数据,否则可以使用缓存

如果一个请求消息头中同时包含 If-Modified-Since 和 If-None-Match 字段,那么 If-None-Match 优先级更高。先判断 If-None-Match,如果不匹配直接无法使用缓存,如果匹配,再根据 If-Modified-Since 判断

问题:为什么 Etag 的优先级更高??

Etag 是服务器中资源的唯一标识,它可以解决一些 Last-Modified 难以解决的问题

强制缓存和协商缓存区别:强制缓存不需要将请求发送给服务器,浏览器自己可以决策;协商缓存需要将请求先发送给服务器,由服务器决策,如果可以使用缓存会响应一个 304 的消息,表示缓存重定向

总流程图

下面给出缓存策略的总体流程图:

3

注意:

参考文章