问题描述
发版完后有用户反馈输入网址进行访问,进入页面后白屏,刷新后正常,点开某个按钮跳转到其他路由后又是白屏,刷新之后正常。后面复现问题后发现白屏的时候报错了,报错是因为index.html中引用的js的响应结果为index.html
分析
在没有复现问题之前只能通过推测去验证,首先要弄懂几个问题
1. 状态码和提示的含义
-
状态码:200
该资源浏览器中没有缓存,从服务器中直接请求最新资源并返回
image.png -
状态码200 + 磁盘缓存(disk cache) / 内存缓存
该资源浏览器中有缓存,并且缓存还有效,直接返回缓存中的资源
image.png -
状态码:304
该资源浏览器中有缓存,并且去服务器里面验证了资源没有更新,返回缓存中的资源
image.png
2.通过不同方式访问浏览器时的区别
注意:下面均在没有配置任何缓存策略的情况下,测试第二次访问网站时的区别
-
输入网址访问页面
从图片可以看出,返回的资源都是浏览器缓存的资源,并且没有请求过服务器
image.png -
正常刷新浏览器
(刷新浏览器的方式包括:点击刷新按钮、点击正常重新加载、在地址栏点回车刷新)
image.png
image.png
从图片可以看出:请求html资源时,去到了服务器中获取资源,但是发现资源并没有变化,于是返回了304命中了协商缓存。请求js直接返回的缓存的资源
为什么html和js的结果不一样?
HTML和JavaScript的缓存方式可能会不同,这取决于浏览器的缓存策略。
通常情况下,浏览器会将HTML文件标记为“不可缓存”,这意味着每次刷新网页时,都会从服务器重新获取HTML文件。而对于JavaScript文件,浏览器可能会使用“缓存验证”技术,即在请求JavaScript文件时会向服务器发送一个验证请求,如果服务器返回的响应表明该文件未发生更改,则浏览器将从缓存中获取文件,否则将重新从服务器下载文件。
因此,在某些情况下,即使您刷新了网页,JavaScript文件仍可能从浏览器缓存中获取。但是,如果您使用的是强制刷新,浏览器将忽略缓存并重新下载所有内容,包括HTML和JavaScript文件。
-
强制刷新浏览器
强制刷新浏览器的方式:
image.png
从图片可以看出:js和html都是从服务器里面获取的最新资源,并且并不会判断资源是否有更新,而是直接从服务器获取了最新的资源,命中了强缓存策略。
注意:强制刷新并不是忽略缓存,而是会去清除缓存
-
清空缓存并重新加载
image.png
清缓存后刷新和强制刷新看起来似乎并没有什么区别,但他们最大的区别在于,强制刷新只对当前页面下的资源缓存进行清除,而手动清除缓存会对整个浏览器中该域名下的所有缓存进行清除
现在已经确定了刷新后html一定会获取到最新的资源,而最新的资源加载是正常,旧的资源加载异常
刷新正常后跳转到其他页面后为什么又异常了
访问首页时
访问其他页面时
虽然他们都指向的都是index.html,但是浏览器在判断是否读取缓存时,通常是根据资源的 URL 地址而不是文件内容进行判断的,所以即使在刷新之后获取了最新的html,但是在访问其他页面时由于没有刷新所有还是获取的缓存的资源。
解决方法
nginx增加配置,使index.html不缓存
location = /index.html{
add_header Cache-Control "no-cache";
}