HTTP的缓存机制
浏览器缓存一般分为两类,强缓存(本地缓存)和协商缓存(也称弱缓存);
- 本地缓存阶段
浏览器发送请求之前,会先去缓存里面查看是否命中强缓存,如果命中,则直接从缓存中读取资源,不会发送请求到服务器,否则,进入下一步。
- 协商缓存阶段
当强缓存没有命中时,浏览器一定会向服务器发起请求,服务器会根据
Request Header中的一些字段来判断是否命中协商缓存。如果命中,服务器会返回304响应,但是不会携带任何响应实体,只是告诉浏览器可以直接从浏览器缓存中获取这个资源。如果本地缓存和协商缓存都没有命中,则直接从服务器加载资源。
按照本地缓存阶段和协商缓存阶段分类
在HTTP请求和响应的消息报头中,常见的于缓存有关的消息报头有
缓存位置
浏览器可以在内存,硬盘中开辟一个空间用于保存请求资源副本
- 内存缓存 (200 from memory cache)
表示不访问服务器,直接从内存中读取缓存,因为缓存的资源保存在内存中,所以读取速度比较快,但是关闭进程后,缓存资源也会随之销毁,一般来说,系统不会给内存分配较大的容量,因此内存缓存一般用于存储较小文件,同时内存缓存在有时效性要求的场景下很有用
- 硬盘缓存 (200 from disk cache)
表示不访问服务器,直接从硬盘中读取缓存。与内存相比,硬盘的读取速度相对较慢,但硬盘缓存持续的时间更长,关闭进程后,缓存的资源仍然存在,由于硬盘的容量较大,因此一般用于存储大文件。
整体流程
详细信息
- 强缓存
- expires
- http1.0定义的字段,表示过期时间,格式如:expires: Mon, 29 Mar 2021 01:03:05 GMT, 表示在这个时间之前,如果客户端需要再次获取这个资源,不会向服务器中取,会直接在缓存里面读取。
- cache-control
- http1.1定义的字段,表示缓存的时间长度,格式如:cache-control: max-age=2592000,单位为秒,表示可以缓存的时间是30天。
- no-cache: 表示不进行强缓存,但不影响协商缓存;
- no-store:既不强缓存,也不协商缓存;
- 两者优先级:cache-control的优先级高于expires;
- expires
- 协商缓存
- 1,
last-modified与if-modified-sincelast-modified表示该文件上一次被修改的时间,格式如
last-modified: Tue, 04 Aug 2020 14:54:28 GMT,当客户端第一次向服务器第一次请求时,服务器会在响应头上带上最后修改时间last-modified,等到第二次客户端向服务器请求同样的资源时,客户端会在请求头上的if-modified-since带上上一次请求的last-modifed值,服务器对最后一次修改时间进行比较,如果时间一致,服务器返回304状态码,客户端直接在缓存中读取数据,如果不一致,服务器返回200的状态码,并更新文件 - 2,
etag与if-none-matchetag表示文件的唯一标识,格式如
etag: "5f2976a4-17d", 当客户端第一次向服务器第一次请求时,服务器会在响应头上带上文件唯一标识etag,等到第二次客户端向服务器请求同样的资源时,客户端会在请求头上的if-none-match带上上一次请求的etag值,服务器对etag进行比较,如果时间一致,服务器返回304状态码,客户端直接在缓存中读取数据,如果不一致,服务器返回200的状态码,并更新文件 - 两者区别:
- etag的出现解决了last-modified所存在的一些问题
- 当周期性的更改文件的时间,但是并没有更改文件的内容时
- last-modified只能精确到秒,如果一个文件在1秒内更改了多次,那么无法更新到最新的数据,而
etag的精确度更高 - 某些服务器不能精确的得到文件的最后修改时间
- 两者如何使用
last-modified与etag是可以一起使用的,服务器会优先验证etag,一致的情况下,才会继续对比last-modified, 最后才决定是否返回304
- 1,