HTTP 缓存是什么?

2019-01-24  本文已影响0人  YOJIN

为什么需要缓存?

节省资源,节省流量,节省时间,也就是所谓的优化。

怎么缓存?

缓存可以简单的划分成两种类型:强缓存(200 from cache)与协商缓存(304)

区别简述如下:

以下,分别介绍。

Expires

在 HTTP Response Header 中添加 Expires 字段,表示 Cache 到期时间。

Expires: Wed, 21 Oct 2015 07:28:00 GMT

浏览器收到这个 Response 之后会把资源缓存到本地,当浏览器再次访问当前页面需要请求该资源时,浏览器会检查现在的时间是否超过 Expires 设置的时间。 如果没有超过,浏览器便不会发送请求,而是直接使用缓存的资源。


通过Chrome开发工具可查看到上图的信息,代表这个请求未发出,使用的是本地缓存。

但是 Expires 存在一个问题,浏览器检查这个 Expires 的时间用的是电脑自身的时间,而设置 Expires 时间的是服务器,所以会存在服务器与客户端两者时间不同步的情况,这会使缓存无效。

Cache-Control

Expires 是 http 1.0 就存在的缓存控制 Header ,存在上述的缺陷,所以在 http 1.1 中出了新的缓存控制 Header ,Cache-Control

设置缓存时间的用法是 Cache-Control: max-age=30 ,这代表这个 Response 的缓存时间为 30秒,这个时间是相对于请求的时间。

提及一下,Cache-Control 的优先级比 Expires 更高,也就是说,在 Cache-Control 设定 max-age 的情况下,以 max-age 作判断依据。

当资源过期了

ExpiresCache-Control 设定的期限之前,都是不发送请求,资源都是从本地缓存中获取,当超过期限时,就会发送请求到服务器,进入一个协商缓存的判断。

唔,协商缓存可以这么理解……

比较资源的方法就是通过 Last-ModifiedE-tag

Last-Modified

这个是 http 1.0 中就存在的方法,Last-ModifiedIf-Modified-Since 搭配使用。

在服务器发送资源时,在响应头中添加一个 Last-Modified 头部,表示这个资源上次更改的时间。当缓存过期时,浏览器发送请求,请求头中携带 If-Modified-Since 信息(资源上次更改的时间), 服务器利用这个信息来判断。

如果在这段时间,资源都不曾变更过,则服务器会回一个 Status code : 304 (Not Modified) ,表示浏览器可以继续沿用这份资源。

不过这个方法存在一个缺点,它所谓的资源变更指的是编辑时间有无变化。当你将资源点开,然后保存关闭,编辑时间就变化了,就会引起所谓的变更,但是内容却和之前没任何的不同,还是一模一样的。

所以比起判断编辑时间,以内容是否有变更作为判断依据会更方便,就有了 E-tag

E-tag

这个是 http 1.1 中的方法,E-tagIf-None-Match 搭配使用。

获取资源的 MD5 值,将该值设置给 E-tag 响应头,然后服务器将响应发送给浏览器,当缓存过期时,浏览器发送请求,请求头中携带 If-None-Match 信息(MD5 值), 服务器利用这个信息来判断。

MD5:是一种指纹机制,代表文件相关指纹,只有文件变才会变,也只要文件变就会变。

如果在这段时间,资源不曾变更过(MD5 值没变化),则服务器会回一个 Status code : 304 (Not Modified) ,表示浏览器可以继续沿用这份资源。

首页的缓存策略

对于静态资源一般都设置缓存,但一个网站首页会特殊些,因为网站首页的变动频率相较静态资源来说会更为高,而且一有变动便希望用户能立即看到变化,要到达这个目的就需要实现:缓存首页,只要首页一变动就立即更新缓存。

方法1:Cache-Control: max-age = 0

这个表示缓存在零秒后过期,浏览器访问网页时会向服务器发送请求,由 E-tag 来判断是使用缓存,还是更新缓存。

方法2:Cache-Control: no-cache

这个表示缓存资源,但浏览器访问网页时不优先使用缓存,会向服务器发送请求,由 E-tag 来判断是使用缓存,还是更新缓存。

方法2 和 方法1 几乎一样。

值得注意的是 Cache-Control: no-cacheCache-Control: no-store 间的差异。

Cache-Control: no-cache 是不使用本地缓存。需要使用缓存协商,先与服务器确认返回的响应是否被更改,如果之前的响应中存在ETag,那么请求的时候会与服务端验证,如果资源未被更改,则可以避免重新下载。

Cache-Control: no-store 是直接禁止浏览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源。

强缓存如何重新加载缓存缓存过的资源

上面说到,使用强缓存时,浏览器不会发送请求到服务端,根据设置的缓存时间浏览器一直从缓存中获取资源,在这期间若资源产生了变化,浏览器就在缓存期内就一直得不到最新的资源,那么如何防止这种事情发生呢?

通过更新页面中引用的资源路径,让浏览器主动放弃缓存,加载新资源。

这样每次文件改变后就会生成新的query值,这样query值不同,也就是页面引用的资源路径不同了,之前缓存过的资源就被浏览器忽略了,因为资源请求的路径变了。

示意图:

http 1.0 与 http 1.1 浏览器第一次请求时 浏览器后续在进行请求时
上一篇 下一篇

猜你喜欢

热点阅读