【强缓存与协商缓存】


以下问题分析为个人见解,如有错误还请指正!

因缓存遇到的问题

工作中遇到图片中的现象,每次重新部署后会遇到样式丢失的问题。在这里插入图片描述
通过Chrome的控制台分析原因,发现vue scope增加的组件属性选择器data的值在dom上的与css文件中的值不一致。
???脑子里面第一闪过的是,怎么会出现这样子的情况,本地打包查看发现也是完全一致的情况

问题分析过程

通过对jenkins中打包文件的输出与浏览器加载资源问价的hash比对发现,浏览器控制台一直在使用缓存的资源
jenkins打包输出的runtime.js(css构建产生的hash值在这个运行时的依赖文件中存储)在这里插入图片描述
浏览器加载的runtime.js的hash值
在这里插入图片描述

问题一:为什么会使用了缓存呢?

出现上述问题的情况步骤是:通过a标签的href跳转,浏览器地址栏输入url回车,F5或浏览器刷新按钮都会有这样子的问题。勾选禁用缓存强制拉取最新资源的情况是正常的,这也变相说明远程服务器的资源文件没有因为构建打包导致混乱。
在这里插入图片描述

我在网上查找了一下原因,大致如下(以下是再不打开控制台或者即使打开了控制台也没有勾选Disabled cache):
a标签的href跳转和浏览器输入url回车,浏览器会以最少的请求来获取网页内容。这句话变相告诉我们,只要强缓存没有过期,就用本地的缓存吧,也不用发送请求到服务器协商缓存有没有过期了。
在这里插入图片描述

Cache-Control:max-age=86400,也就是这个入口html文件有24小时的有效期。所以这就是为什么会看到上面runtime.js与jenkins构建的文件hash不一致。

然后问题又来了,既然a标签的href跳转和浏览器输入url回车是强制使用了本地缓存,那不是还有F5吗,F5会发起请求到远程服务协商缓存是不是有效吗?

是的,正常来说应该是服务器判断出资源已经更新了,然后返回一个200的相应并携带最新的资源的响应体信息。但是我们的服务在构建之后返回的依然是304(not modified),告诉浏览器服务器资源没有更新协商缓存通过了,所以浏览器使用的还是本地的缓存。
在这里插入图片描述
我又在网上查了一下。ETag虽然是作为资源文件的唯一标识,但是ETag存在强弱两种类型。强ETag是无论资源实体发生了怎么样的变化,值都会发生变化。弱ETage只用于提示资源是否相同,只有资源发生了根本的变化才会变化,弱Etag的表现形式就是前面有一个W/。然后我询问了一下AI,AI告诉我引入文件中的hash串发生变化也是根本变化,所以最根本的原因是服务器缓存策略ETag出现了问题,导致协商缓存通过了,一直使用的本地的缓存,才没有请求到最新的资源。

问题二:就算是使用了缓存,那只要构建版本是一致的版本,也不会出现DOM中的data属性值与css中的属性器data的值不一致的情况吧!

目前我只能大致猜测原因如下:
第一次构建完成之后,页面访问获取的都是最新的资源,本地会缓存当前版本的资源。
然后新版本构建完成后,打开页面(a标签href跳转),默认使用强缓存,现在runtime.js中依赖的css版本是就版本。这个时候直接打开页面样式是正常的,只是增加的内容或者逻辑不会变化,因为都是用的强缓存。但是开发者会勾选chrome控制台当中的Disbale Cache,这个时候再点击路由请求资源文件的时候发起的请求会如下图片。因为没有hash,所以请求的资源会是最新的资源,这样本地与远程拉取的资源就出现了版本错位
在这里插入图片描述
最后js文件执行挂载dom已经dom的属性data值的时候就与runtim.js中依赖的运行时的css资源的属性选择器不一样了。
从而导致了样式不能挂载到对应的dom资源中

本人项目jenkins构建完成后推送远端大致命令如下。

# 前面并不存在 ssh root@[远端ip] 'rm -rf [远端静态资源路径]/*'这样子的删除所有文件的命令
scp -r dist/* root@[远端ip]:[远端静态资源路径]

所以同名文件会覆盖,新文件会增加,旧文件不会删除。所以我的推测可能是会成立的。

加下本地复现流程

当前最新版浏览器和构建文件,可以看到现在文件的拉取是一致的
在这里插入图片描述
修改页面内容之后可以看到,css的hash值已经改变了,构建的js虽然没有hash值,但是内容也发生变化了
在这里插入图片描述
在这里插入图片描述
新版jenkins构建目标文件。因为css文件是整个文件夹推过去的,所以暂时看不到css的hash
在这里插入图片描述
本地href跳转之后,打开控制台禁用缓存然后跳转路由,我们看下请求的目标js文件是带有最新的改动的
在这里插入图片描述
然后我们看下控制台源代码文件就一目了然了,确实如上所说,导致的新旧资源错位了
在这里插入图片描述

个人见解

没有hash后缀的资源文件远端服务器返回时响应头中最好禁用缓存,即Cache-Control:no-store或者no-cache;这样子前者默认不会使用缓存,后者回到服务器进行协商缓存(前提是协商缓存机制无问题)。带有hash后缀的文件每次变换之后文件hash会变化,从而使得资源访问路径发生变化,继而请求到最新的资源文件(即使对于带有hash后缀文件的协商缓存机制出现问题)。

强缓存与协商缓存

缓存相关的http header

强缓存

header请求或响应头描述
Cache-Control响应头或请求头指定缓存机制,优先级高于express
Express响应头或请求头指定缓存过期时间,兼容http1.0
Cache-Control机制值
no-store禁用缓存,包括协商缓存
no-cahce相当于max-age:0,每次都要进行协商缓存
max-age缓存内容多久失效
public整个网路链路都可缓存(客户端,代理服务器等)
private只能客户端进行缓存

协商缓存

header请求或响应头描述
ETag响应头资源唯一标识符,存在强弱两种标识
If-None-Match请求头携带ETag的值
Last-Modified响应头资源最后一次修改的时间
If-Modified-Since请求头携带Last-Modified的值

ETag/If-None-Match这个对的优先级高于Last-Modified/If_modified-Since。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值