背景
最近的vue项目中,为了保证每次发版后用户都能及时更新资源,在每次打包后生成的文件名中都加入了 timeStamp。但是如果用户在发版前就进入了页面A,并且停留,然后等待发版完成,此时用户点击按钮跳转B页面,就会出现B页面的css js等资源加载全部404。 碰到会刷新的用户还好,若用户不刷新硬杠真是没得办法。
解决
直接说解决办法
- 通过
window.addEventListener监听资源加载报错
//main.js
window.addEventListener('error', (e) => {
// 防止刷新过后资源依然404导致页面无限刷新, 在router.afterEach里删除
if (sessionStorage.staticReload) {
return
}
let localName = e.target.localName
if (localName === 'script' || localName === 'link') {
// 只刷新一次 用 staticReload 标记一下
window.sessionStorage.setItem('staticReload', '1')
// reload里一定要加 true
window.location.reload(true);
}
// 这个true一定要加,否则监听不到
}, true)
// router.js
// 跳转成功,说明css js资源加载成功,则去掉 staticReload 标记
router.afterEach(() => {
sessionStorage.removeItem('staticReload')
})
注意点
- window.addEventListener 的第三个参数 一定要是
true,表示用事件捕获。 - window.location.reload(true) 里一定要用
true, 表示直接从服务器取资源。 - 加一个标记,只刷新一次就够了,因为如果是因为某个资源本身不存在导致刷新完又404,会让页面无限刷新。我们解决的只是能保证刷新页面就能获取到的正常打包资源。
结语
这样一旦用户停留页面的时间正好跨越了发版时间,资源加载404的情况下,会直接在当前页面强行刷新一下,然后就能正常使用了。