客户端缓存处理(强缓存和协商缓存):都是对资源文件的缓存处理,数据的缓存不是这样处理的
缓存的位置:
Memory Cache : 内存缓存
Disk Cache:硬盘缓存
打开网页:查找 disk cache 中是否有匹配,如有则使用,如没有则发送网络请求
普通刷新 (F5):因TAB没关闭,因此memory cache是可用的,会被优先使用,其次才是disk cache
强制刷新 (Ctrl + F5):浏览器不使用缓存,因此发送的请求头部均带有 Cache-control: no-cache,服务器直接返回 200 和最新内容
强缓存
- Expires:Tue, 01 Dec 2020 13:50:37 GMT HTTP1.0 (客户端和服务器端可能会有时间差)
- Cache-Control:max-age=14400 HTTP1.1
-
这些都是服务器设置的,并且基于响应头信息返回给客户端的(nginx这些发布工具直接搞定的);客户端浏览器接收到响应后,会自己建立缓存机制(不需要前端自己写代码);
强缓存存在的问题
- 客户端缓存信息了,但是服务器的资源文件更新了「项目新版本上线部署」,这样导致用户无法及时获取到服务器最新资源信息
解决办法
- xxx.html这种页面不进行强缓存
- xxx.css/js/png...可以强缓存:因为html没有强缓存,所以每一次html都是从服务器获取的,如果其它资源文件服务器有更新,我们只需要在html中导入资源的时候做处理即可
- 导入路径后面设置时间戳
- 资源文件的名字在内容发生更改后,名字会重新生成「HASH名字 ->webpack」
协商缓存:在强缓存失效的情况下,协商缓存的机制才会触发
- Last-Modified/If-Modified-Since:Tue, 02 Apr 2019 04:33:32 GMT HTTP1.0
设置Last-Modified->如果1秒内 客户端拿到了资源文件 同时服务器端在客户端拿了资源文件后恰巧更新 客户端是拿不到最新文件的 -
ETag/If-None-Match:"700e28-17667-58584a3b7eca0" HTTP1.1
下面都是认为没有强缓存或者强缓存失效了
- 第一次请求,没有任何缓存,直接从服务器获取资源和标识Last-Modified/ETag(状态码返回的是200),页面渲染同时,存储到本地;
- ...
- 第N次请求,检测本地是否有存储的标识,如果没有认为没缓存,重复上一个步骤,如果有:
- 基于标识If-Modified-Since/If-None-Match,把之前存储的Last-Modified/ETag结果,传递给服务器
- 服务器收到结果做匹配
- 服务器端一般这样处理的,在项目文件部署的时候,会生成Last-Modified/ETag对应的值,这个值代表当前项目文件在服务器上最后一次更新的时间或者对应的标识
- 接收到客户端传递的结果,和之前存储的值进行比较,如果一致说明文件没有更新,给客户端直接返回304状态码即可,如果不一致说明文件有更新,则把最新的文件信息及标识信息重新返回给客户端,状态码是200
- 服务器收到结果做匹配
-
- 客户端收到响应后,判断状态码
- 304,把之前缓存的文件拿出来渲染
- 200,按照最新的文件渲染,同时更新本地的缓存