浏览器缓存(HTTP)

145 阅读5分钟

强缓存

这是最优先的缓存规则,如果强缓存成功,不会向服务器发送请求,直接从缓存中读取资源

强缓存主要从两个参数考虑ExpiresCache-ControlCache-Control的优先级高于Expires

Expires

参考资料

developer.mozilla.org/zh-CN/docs/…

www.geeksforgeeks.org/http-header…

Expires:Sat, 20 Nov 2021 16:16:00 GMT (返回格式必须是GMT)

Expires 是 HTTP/1 的产物,受限于本地时间,如果修改了本地时间,可能会造成缓存失效 注意:HTTP 日期中表示的时间应始终保持格林威治子午线时间 (GMT) 而不是当地时间,如果在中国这个时间需要加8个小时才是正确的,上面的过期时间如果浏览器的设置是中国的话,那么过期时间实际上是Sat, 21 Nov 2021 00:16:00,会根据时区不同有所变化,这点是我在验证过程中发现的 image.png image.png 这是第一次请求,Expires: Sat, 20 Nov 2021 09:40:00 GMT,电脑时间为16:52,实际过期时间为15:40 image.png 第二张可以看到直接从硬盘获取数据了,因为在缓存时间内 我们通过修改Expires返回代码的时间 image.png 清空浏览器数据再次请求 image.png image.png 可以看到第一次时间设置了Expires: Sat, 20 Nov 2021 08:40:00 GMT,但是第二次还从服务器请求数据了,那是因为实际的缓存时间是16:40,已经过期了,所以浏览器重新从服务端取最新的数据

Cache-Control

参考资料

developer.mozilla.org/zh-CN/docs/…

通用消息头字段,被用于在http请求和响应中,通过指定指令来实现缓存机制。缓存指令是单向的,这意味着在请求中设置的指令,不一定被包含在响应中。

Cache-Control的优先级是高于Expires的。

image.png image.png 可以看到Expires失效了,Cache-Control的缓存时间为3s

更多使用方法可以参考MDN文档

协商缓存

协商缓存是强缓存失效之后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程,主要包括以下两个情况

协商缓存生效,返回304 Not Modified

协商缓存失效,返回200和请求结果

接着我们来看 Last-Modified ,要注意的是,这里必须设置 maxAge: 0 ,因为 Last-Modified 和 ETag 是在 Cache-Control: max-age=0 的基础上生效的。

Last-ModifiedIf-Modified-Since

  1. 浏览器首先发送一个请求,让服务端在response header中返回请求的资源上次更新时间,就是last-modified,浏览器会缓存下这个时间。
  2. 然后浏览器再下次请求中,request header中带上if-modified-since:[保存的last-modified的值]。根据浏览器发送的修改时间和服务端的修改时间进行比对,一致的话代表资源没有改变,服务端返回正文为空的响应,让浏览器中缓存中读取资源,这就大大减小了请求的消耗。

第一次请求

image.png F5刷新请求,可以看到服务端收到if-modified-since之后判断本地文件修改时间是否一致,一致就返回304 image.png 修改test.js文件的内容,可以看到两个值并不一样就返回200和对应的资源 image.png 注意:由于last-modified依赖的是保存的绝对时间,还是会出现误差的情况

  1. 保存的时间是以秒为单位的,1秒内多次修改是无法捕捉到的。
  2. 各机器读取到的时间不一致,就有出现误差的可能性。为了改善这个问题,提出了使用etag。

ETag和if-none-match

ETaghttp协议提供的若干机制中的一种Web缓存验证机制,并且允许客户端进行缓存协商。生成etag常用的方法包括对资源内容使用抗碰撞散列函数,使用最近修改的时间戳的哈希值,甚至只是一个版本号。 和last-modified一样. - 浏览器会先发送一个请求得到ETag的值,然后再下一次请求在request header中带上if-none-match:[保存的etag的值]。 - 通过发送的ETag的值和服务端重新生成的ETag的值进行比对,如果一致代表资源没有改变,服务端返回正文为空的响应,告诉浏览器从缓存中读取资源。

etag能够解决last-modified的一些缺点,但是etag每次服务端生成都需要进行读写操作,而last-modified只需要读取操作,从这方面来看,etag的消耗是更大的。

二者对比 - 精确度上:ETag要优于Last-Modified。 - 优先级上:服务器校验优先考虑Etag。 - 性能上:ETag要逊于Last-Modified

下图if-none-matchEtag不一样就返回200

image.png 下图if-none-match和Etag一样就返回304

image.png

from disk cachefrom memory cache

Chrome的网络请求的Size会出现三种情况from disk cache(磁盘缓存)from memory cache(内存缓存)、以及资源大小数值 image.png

状态类型说明
200from memory cache不请求网络资源,资源存在内存当中,一般脚本,字体,图片会存在内存
200from disk cache不请求网络资源,资源存在磁盘当中,一般非脚本会存在
200资源大小数值从服务器中下载最新资源
304报文大小请求服务发现资源没有更新,使用本地资源

浏览器读取缓存的顺序为memory –> disk

总结

image.png