浏览器缓存机制


(PS:这篇文章,就是纯粹的纸上谈兵哈,并没有实践过。所以一定要自己动手试试。)

浏览器缓存的基本原理

1)浏览器在加载资源时,根据请求头的expirescache-control判断是否命中强缓存,是则直接从缓存读取资源,不会发请求到服务器。

2)如果没有命中强缓存,浏览器一定会发送一个请求到服务器,通过last-modifiedetag验证资源是否命中协商缓存,如果命中,服务器会将这个请求返回,但是不会返回这个资源的数据,依然是从缓存中读取资源

3)如果前面两者都没有命中,直接从服务器加载资源

浏览器缓存类型:

浏览器的缓存分为两种:强缓存和协商缓存。

强缓存:不会向服务器发送请求,直接从缓存中读取资源。

协商缓存:向服务器发送请求,服务器会根据这个请求的request header的一些参数来判断是否命中协商缓存,如果命中,则返回304状态码并带上新的response header通知浏览器从缓存中读取资源;

区别

共同点:两者都是从客户端缓存中读取资源;区别:强缓存不会向服务器发送请求,协商缓存会向服务器发送请求。

强缓存相关字段

Expires和Cache-Control

1)Expires

Expires是http1.0提出的一个表示资源过期时间的header,它描述的是一个绝对时间,由服务器返回。 Expires 受限于本地时间,如果修改了本地时间,可能会造成缓存失效

Expires: Wed, 11 May 2018 07:20:00 GMT

2)Cache-Control

Cache-Control 出现于 HTTP / 1.1,优先级高于 Expires ,表示的是相对时间。

相对Expires而言,max-age是距离请求发起的时间的秒数。

Cache-Control: max-age=315360000

协商缓存相关字段

协商缓存是利用的是【Last-Modified,If-Modified-Since】和【ETag、If-None-Match】这两对Header来管理的。

1)Last-Modified,If-Modified-Since

Last-Modified 表示本地文件最后修改日期,浏览器会在request header加上If-Modified-Since(上次返回的Last-Modified的值),询问服务器在该日期后资源是否有更新,有更新的话就会将新的资源发送回来

但是如果在本地打开缓存文件,就会造成 Last-Modified 被修改,所以在 HTTP / 1.1 出现了 ETag

2)ETag、If-None-Match

Etag就像一个指纹,资源变化都会导致ETag变化,跟最后修改时间没有关系,ETag可以保证每一个资源是唯一的

If-None-Match的header会将上次返回的Etag发送给服务器,询问该资源的Etag是否有更新,有变动就会发送新的资源回来

3)ETag的优先级比Last-Modified更高

具体为什么要用ETag,主要出于下面几种情况考虑:

  • 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;
  • 某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒);
  • 某些服务器不能精确的得到文件的最后修改时间。

浏览器缓存机制:强缓存、协商缓存

浏览器的缓存机制小结