某个系统程序运行中,点击菜单,请求https://www.xxx.xxx.cn/assets/js/inside_menu-PWLikSoI.js,十小时对该系统不操作,再次点击报错
问题描述某个系统程序运行中点击菜单请求https://www.xxx.xxx.cn/assets/js/inside_menu-PWLikSoI.js十小时对该系统不操作再次点击菜单 报错vue-DN7Vng0Z.js:13 TypeError: Failed to fetch dynamically imported module: https://www.xxx.xxx.cn/assets/js/inside_menu-PWLikSoI.js解决这是一个非常典型的前端单页应用SPA缓存失效问题。简单来说系统在长时间10小时不操作后浏览器本地保存的“旧地图”主程序代码与服务器上最新的“新建筑”菜单文件对不上了导致程序找不到路从而报错。Vue.js报错信息中的 vue…js 表明该系统是基于 Vue 框架开发的单页应用。动态导入dynamically imported module 意味着菜单代码是按需加载的只有点击时才下载而不是在系统启动时一次性全部下载。文件指纹inside_menu-PWLikSoI.js 文件名中的 PWLikSoI 是哈希值指纹。只要文件内容修改这个后缀就会变例如变成 inside_menu-AbC123.js。这个问题通常由“版本不匹配”引起具体流程如下初始状态T0你打开系统浏览器下载了主程序包含旧的路由映射表指向 inside_menu-PWLikSoI.js。后台更新T5小时开发人员在服务器端更新了系统重新打包了代码。此时菜单文件变成了新的哈希值例如 inside_menu-XyZ987.js旧的 inside_menu-PWLikSoI.js 可能已被删除或覆盖。长时间闲置T10小时你的浏览器仍然停留在 T0 的状态内存中保存的仍然是旧的路由映射表。触发错误当你再次点击菜单时旧的主程序试图去请求旧的 inside_menu-PWLikSoI.js。但服务器说“这个文件已经不存在了404”或者“文件已更新”导致浏览器无法加载该模块抛出 Failed to fetch 错误main.ts中添加下面的代码// 1. 保存原始的 push 方法constoriginalPushrouter.push;// 2. 重写 push 方法以捕获 ChunkLoadError// 注意这里使用了 any 来绕过 TypeScript 的类型检查因为标准类型定义未包含此错误处理逻辑(routerasany).pushfunctionpush(location:any){returnoriginalPush.call(this,location).catch((err:any){console.log(err:,err);// 3. 判断是否为代码块加载错误if(err.nameChunkLoadError||err.message.includes(Failed to fetch dynamically imported module)){console.warn(检测到版本更新正在自动刷新页面...);// 强制刷新页面重新获取最新资源window.location.reload();}else{// 如果是其他错误保持原有逻辑例如导航重复等returnPromise.reject(err);}});};进阶方案针对 Vite 用户// 仅在 Vite 项目中有效window.addEventListener(vite:preloadError,(event){event.preventDefault();// 阻止默认的错误抛出window.location.reload();// 直接刷新});