Vue,react单页项目更新后的白屏问题,及微信浏览器的坑

现象

项目更新后,部分用户出现打开白屏。设备为Android版本的微信,猜测为非Google Play版本。IOS不受影响

猜测原因

  • 经过测试后,Nginx设置了Etag及expires,导致Index.html文件二次请求时返回304。
  • 由于采用了协商缓存,在服务器更新代码后Chrome及微信开发工具正常。
  • 资源文件在webpack打包后,文件名中会带上Hash值,所以每次打包的文件名都不一样。
  • 根据以往经验,猜测为代码更新后,未拿到新版index.html文件,导致资源文件404。

解决方案

关于协商缓存可以去搜索,或者这篇文章

https://juejin.im/post/5c09cbb1f265da617006ee83

将Nginx设置为,index.html文件强制不缓存,其他文件缓存。
配置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server {
listen 80;
server_name xxx.com;
index index.html index.html index.html;
root D:/code/Vue/testt/dist;

# 以下为关键部分
location = /index.html {
add_header Last-Modified $date_gmt;
add_header Cache-Control 'no-cache, must-revalidate, proxy-revalidate, max-age=0';
if_modified_since off;
expires -1s;
etag off;
}
}

配置完成后,每次访问网页都会重新获取index.html文件,js、css文件将会缓存到本地。

微信浏览器的坑

  • 按理说解决了,但实际上客户依然反应白屏。由于机器在客户那里,且bug无法复现,陷入困境。难道是获取不到Index.html文件?
  • Google后有人提出: 微信浏览器国内版用的腾讯X5内核,表现与开发工具、Chrome不一致,不会有协商缓存这一步。
  • 完蛋!采用协商缓存的话浏览器会询问服务器文件是否更新,如果没有这步,则永远拿不到新版文件了。
  • 于是想到一个机智的解决方式,因为可以拿到新版文件所以一定会请求旧版文件,那么我给他不就行了吗。然后强制刷新。
  • 找出以往发布过的代码,在4月发布过版本,之后则是6月的几次。找出其中app.[Hash].js的文件名,每个文件名都新建一个,只写入window.location.reload()强制刷新
  • 让客户继续测试,问题解决。