浏览器缓存的理解

241 阅读5分钟

一、缓存

缓存是浏览器的一种机制,可以把请求过的web资源(html、css、js、图片等),拷贝一份存储在浏览器中,并根据请求配置是否使用该副本。

二、缓存分类

缓存从宏观上分为共享缓存和私有缓存,共享缓存就是那些能被各级代理缓存的缓存; 私有缓存是用户专享的,各级代理不能缓存的缓存。

缓存从微观上可以分为 (1)、浏览器缓存 (2)、代理服务器缓存 (3)、CDN缓存 (4)、数据库缓存 (5)、应用层缓存

三、浏览器缓存

浏览器缓存总体上分为(1)、强缓存  (2)、协商缓存

3.1 强缓存

==》 (不发任何请求直接从浏览器中获取数据)

(1)、HTTP 1.0: Expires
(2)、HTTP 1.1:Cache-control

判断的过程: 请求再次发起 => 浏览器根据expires 和 cache-control 判断目标资源是否命中“强缓存” => 若命中,直接从缓存中获取资源,不再与服务器发送通讯。

ps: 如果cache-control 与 expires 同时存在,则以cache-control为主,继续使用expires的目的就是为了向下兼容。

HTTP 1.0: expires的弊端在于: 它的值为一个绝对时间的GMT 格式的时间字符串,这个时间代表着这个资源的失效时间,在次时间前,即命中缓存。   依赖本地时间,它控制缓存的原理是使用客户端的时间与服务端返回的时间做对比,如果有客户端与服务端的时间时区不同或者用户修改了本地时间等原因,导致客户端和服务端有一方的时间不准确的话,那么强缓存则会直接失效。

HTTP 1.1: Cache-Control: cache-control 是HTTP1.1 时出现的header信息,主要是利用该字段的max-age值来进行判断的,它是一个相对时间,例如:cache-control:max-age=3600,代表着该资源的有效期是3600秒,主要字段如下: (1)、public:所有内容都将被缓存,客户端和代理服务器都可缓存;
(2)、private: 所有内容只要客户端可以缓存,cache-control的默认取值;
(3)、no-cache: 客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定;
(4)、no-store: 所有内容都不会被缓存,即不使用强缓存,也不使用协商缓存; (5)、max-age=xxx: 缓存内容将在xxx秒后失效;
(6)、must-revalidate: 强制浏览器严格遵守你设置的cache规则;
(7)、proxy-revalidate: 强制proxy 严格遵守你设置的cache规则。

3.2 协商缓存

 就是强制缓存失效后, 浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用
 缓存的过程,主要有以下两种情况:  

(1)、缓存生效, 返回304 和 Not Modified

(2)、协商缓存失效,返回200 和 请求结果

协商缓存可以通过设置两种HTTP Header实现:Last-Modified 和 ETag

=> HTTP1.0: Last-Modified && If-Modified-Since Last-Modified 是该资源文件的最后一次更新时间,服务器会在Response Headers中返回,浏览器在下一次发送请求时,放到Request Header里的If-Modified-Since里面,服务器在接收到后也会做比对,如果相同则命中协商缓存。

=> HTTP1.1: Etag && If-None-Match Etag 是服务器响应请求时,返回当前资源文件的的一个唯一标识,只要资源有变化,Etag就会重新生成。浏览器在下一次加载资源向服务器发送请求时候,会将上一次返回的Etag值放到Request Header里的If-None-Match 里,服务器只需要比较客户端传来的If-None-Match跟自己服务器上该资源的ETag是否一致。

整个流程:

  • (1)、首次请求;
  • (2)、服务器告知启用协商缓存规则,并在响应头带上Last-Modified,告知缓存到期时间;
  • (3)、随后的每次请求,请求头上都会携带If-Modified,告知缓存到期时间;
  • (4)、服务器收到 If-Modified-Since 后,会将该属性的值与服务器上资源的最后修改时间进行匹配,从而判断资源是否发生了变化;
  • (5)、如果发生变化会返回一个完整的响应内容,在响应头中添加新的 Last-Modified 值,否则,只返回 header 部分,状态码为304,响应头不会再添加 Last-Modified;

对于变动频繁的资源使用:Cache-Control: no-cache => 再配合ETag 或者 Last-Modified 来验证资源是否有效

不常变化的资源使用: Cache-Control:max-age=xxx => 配置一个比较大的max-age,这样浏览器之后请求相同的URL会命中强缓存。

四、缓存位置

浏览器缓存的资源处于:Memory Cache 和 Disk Cache

4.1 Memory Cache

将资源缓存到内存中,等待下次访问时不需要重新下载资源,而是直接从内存
中获取。这个内存容量有限,是个短期缓存,内存缓存的控制权在浏览器,前后端都不能干涉。

4.2 Disk Cache

也叫http cache,其严格遵守http响应头字段来判断哪些资源是否要被缓存,
将资源缓存到磁盘中,等待下次访问时不需要重新下载资源,而是直接从磁
盘中获取,它的直接操作对象为CurlCacheManager。该硬盘缓存的控制权在后端。

五、缓存机制

强缓存优先于协商缓存进行,若强缓存(Expires 和 Cache-Control)生效则直接使用缓存,若不生效则进行协商缓存(Last-Modified / If-Modified-Since 和 Etag /.If-None-Match); 协商缓存由服务器决定是否使用缓存,若协商缓存失效,那么代表请求的缓存失效,返回200并重新返回资源和资源标识,再存入浏览器缓存中; 若生效则返回304,继续使用缓存。