2022年3月

在React或Vue中使用前端路由的history模式时,由于服务端会配合使用URL Rewrite技术,产生的效果就是,SPA页面多个path的请求实际返回的是同一个入口文件。

GET https://idealecho.cn/spa/apath
GET https://idealecho.cn/spa/bpath

Response https://idealecho.cn/spa/index.html

在页面采用强缓存策略的情况下,当服务端文件更新后,用户需要手动刷新页面强行使用协商缓存机制获取最新版本,并更新本地缓存副本。而浏览器对页面进行缓存,使用的key是请求中的path值,这就导致本地会产生多份入口文件的缓存副本,并且版本可能并不一致。

在上例中,浏览器为/spa/apath/spa/bpath两个path分别缓存index.html文件副本,last-modifiedetag可能不同。

除非用户对多个path分别手动刷新,否则很容易造成通过链接在多个path间跳转时,页面在新旧版本间变换。

尤其当开发者对某个path做了自动重定向redirect,让用户很难对原始path手动刷新,也就没法更新对应的缓存。这样即便对其他所有path都进行了刷新,但只要通过前述path进入页面,都会得到页面的旧版本。

解决办法:

第一种,对入口文件index.html设置Cache-Control: no-cache以禁用本地缓存;

第二种,服务端保存一个前端最新产出的版本号,页面定时拉取这个版本号与自身版本号对比,发现过期即刷新页面。