export default defineNuxtPlugin((nuxtApp) => { // 监听并拦截异步 Chunk / 静态资源加载失败的问题(通常是因为服务端重新部署后,旧缓存还在尝试请求被删除的 hash 文件) nuxtApp.hook('app:chunkError', ({ error }) => { console.error('Nuxt Chunk/Asset Loading Failed. Triggering hard reload...', error) // 防止无限刷新,使用 sessionStorage 记录 const reloadCount = parseInt(sessionStorage.getItem('chunk_reload_count') || '0') if (reloadCount < 3) { sessionStorage.setItem('chunk_reload_count', String(reloadCount + 1)) window.location.reload() } else { console.warn('Too many reload attempts for chunk error. Giving up.') } }) // 页面成功加载后清除刷新计数器 nuxtApp.hook('page:finish', () => { sessionStorage.removeItem('chunk_reload_count') }) // 拦截全局未捕获的 Promise 错误,防止它阻塞后续操作(例如因为插件拦截导致的 'A listener indicated an asynchronous response...' 错误) if (import.meta.client) { window.addEventListener('unhandledrejection', (event) => { const err = event.reason?.message || event.reason?.toString() || '' if (err.includes('message channel closed') || err.includes('A listener indicated')) { // 这是常见的浏览器插件注入引起的无害错误,直接忽略 event.preventDefault() } }) // 监听全局 Error 事件,捕获 CSS 等资源的加载失败 window.addEventListener('error', (event) => { const target = event.target as HTMLElement // 检查是否是 link(css) 或 script 的加载错误 if (target && (target.tagName === 'LINK' || target.tagName === 'SCRIPT')) { const href = (target as HTMLLinkElement).href || (target as HTMLScriptElement).src if (href && href.includes('/_nuxt/')) { console.warn('Nuxt static asset failed to load:', href) const reloadCount = parseInt(sessionStorage.getItem('asset_reload_count') || '0') if (reloadCount < 2) { sessionStorage.setItem('asset_reload_count', String(reloadCount + 1)) // 延迟一点刷新以防频繁请求 setTimeout(() => { window.location.reload() }, 1000) } } } }, true) // true = 捕获阶段,以便拦截资源加载错误 } })