强缓存
这是最优先的缓存规则,如果强缓存成功,不会向服务器发送请求,直接从缓存中读取资源
强缓存主要从两个参数考虑Expires和Cache-Control,Cache-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,会根据时区不同有所变化,这点是我在验证过程中发现的
这是第一次请求,Expires: Sat, 20 Nov 2021 09:40:00 GMT,电脑时间为16:52,实际过期时间为15:40
第二张可以看到直接从硬盘获取数据了,因为在缓存时间内
我们通过修改Expires返回代码的时间
清空浏览器数据再次请求
可以看到第一次时间设置了Expires: Sat, 20 Nov 2021 08:40:00 GMT,但是第二次还从服务器请求数据了,那是因为实际的缓存时间是16:40,已经过期了,所以浏览器重新从服务端取最新的数据
Cache-Control
参考资料
developer.mozilla.org/zh-CN/docs/…
通用消息头字段,被用于在http请求和响应中,通过指定指令来实现缓存机制。缓存指令是单向的,这意味着在请求中设置的指令,不一定被包含在响应中。
Cache-Control的优先级是高于Expires的。
可以看到Expires失效了,Cache-Control的缓存时间为3s
更多使用方法可以参考MDN文档
协商缓存
协商缓存是强缓存失效之后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程,主要包括以下两个情况
协商缓存生效,返回304 Not Modified
协商缓存失效,返回200和请求结果
接着我们来看 Last-Modified ,要注意的是,这里必须设置 maxAge: 0 ,因为 Last-Modified 和 ETag 是在 Cache-Control: max-age=0 的基础上生效的。
Last-Modified和If-Modified-Since
- 浏览器首先发送一个请求,让服务端在
response header中返回请求的资源上次更新时间,就是last-modified,浏览器会缓存下这个时间。 - 然后浏览器再下次请求中,
request header中带上if-modified-since:[保存的last-modified的值]。根据浏览器发送的修改时间和服务端的修改时间进行比对,一致的话代表资源没有改变,服务端返回正文为空的响应,让浏览器中缓存中读取资源,这就大大减小了请求的消耗。
第一次请求
F5刷新请求,可以看到服务端收到if-modified-since之后判断本地文件修改时间是否一致,一致就返回304
修改test.js文件的内容,可以看到两个值并不一样就返回200和对应的资源
注意:由于last-modified依赖的是保存的绝对时间,还是会出现误差的情况
- 保存的时间是以秒为单位的,1秒内多次修改是无法捕捉到的。
- 各机器读取到的时间不一致,就有出现误差的可能性。为了改善这个问题,提出了使用etag。
ETag和if-none-match
ETag是http协议提供的若干机制中的一种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-match和Etag不一样就返回200
下图if-none-match和Etag一样就返回304
from disk cache和from memory cache
Chrome的网络请求的Size会出现三种情况from disk cache(磁盘缓存)、from memory cache(内存缓存)、以及资源大小数值
| 状态 | 类型 | 说明 |
|---|---|---|
| 200 | from memory cache | 不请求网络资源,资源存在内存当中,一般脚本,字体,图片会存在内存 |
| 200 | from disk cache | 不请求网络资源,资源存在磁盘当中,一般非脚本会存在 |
| 200 | 资源大小数值 | 从服务器中下载最新资源 |
| 304 | 报文大小 | 请求服务发现资源没有更新,使用本地资源 |
浏览器读取缓存的顺序为memory –> disk