记录---前端如何优雅通知用户刷新页面?
🧑💻 写在开头
点赞 + 收藏 === 学会🤣🤣🤣
前言
老板:新的需求不是上线了嘛,怎么用户看到的还是老的页面呀
窝囊废:让用户刷新一下页面,或者清一下缓存
老板:那我得告诉用户,刷新一下页面,或者清一下缓存,才能看到新的页面呀,感觉用户体验不好啊,不能直接刷新页面嘛?
窝囊废:可以解决(OS:一点改的必要没有,用户全是大聪明)
产品介绍
c端需要经常进行一些文案调整,一些老版的文字字眼可能会导致一些舆论问题,所以就需要更新之后刷新页面,让用户看到新的页面。
思考问题为什么产生
项目是基于vue的spa应用,通过nginx代理静态资源,配置了index.html协商缓存,js、css等静态文件Cache-Control
,按正常前端重新部署后,
用户重新
访问系统,已经是最新的页面。
但是绝大部份用户都是访问页面之后一直停留在此页面,这时候前端部署后,用户就无法看到新的页面,需要用户刷新页面。
产生问题
- 如果后端接口有更新,前端重新部署后,用户访问老的页面,可能会导致接口报错。
- 如果前端部署后,用户访问老的页面,可能无法看到新的页面,需要用户刷新页面,用户体验不好。
- 出现线上bug,修复完后,用户依旧访问老的页面,仍会遇到bug。
解决方案
- 前后端配合解决
- WebSocket
- SSE(Server-Send-Event)
- 纯前端方案 以下示例均以vite+vue3为例;
- 轮询html Etag/Last-Modified
在App.vue中添加如下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | const oldHtmlEtag = ref (); const timer = ref (); const getHtmlEtag = async () => { const { protocol, host } = window.location; const res = await fetch(`${protocol} //${host}`, { headers: { "Cache-Control" : "no-cache" , }, }); return res.headers. get ( "Etag" ); }; oldHtmlEtag.value = await getHtmlEtag(); clearInterval(timer.value); timer.value = setInterval(async () => { const newHtmlEtag = await getHtmlEtag(); console.log( "---new---" , newHtmlEtag); if (newHtmlEtag !== oldHtmlEtag.value) { Modal.destroyAll(); Modal.confirm({ title: "检测到新版本,是否更新?" , content: "新版本内容:" , okText: "更新" , cancelText: "取消" , onOk: () => { window.location.reload(); }, }); } }, 30000); |
- versionData.json
自定义plugin,项目根目录创建/plugins/vitePluginCheckVersion.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import path from "path" ; import fs from "fs" ; export function checkVersion(version: string ) { return { name: "vite-plugin-check-version" , buildStart() { const now = new Date().getTime(); const version = { version: now, }; const versionPath = path. join (__dirname, "../public/versionData.json" ); fs.writeFileSync(versionPath, JSON.stringify(version), "utf8" , (err) => { if (err) { console.log( "写入失败" ); } else { console.log( "写入成功" ); } }); }, }; } |
在vite.config.ts中引入插件
1 2 3 4 5 | import { checkVersion } from "./plugins/vitePluginCheckVersion" ; plugins: [ vue(), checkVersion(), ] |
在App.vue中添加如下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | const timer = ref () const checkUpdate = async () => { let res = await fetch( '/versionData.json' , { headers: { 'Cache-Control' : 'no-cache' , }, }).then((r) => r.json()) if (!localStorage.getItem( 'demo_version' )) { localStorage.setItem( 'demo_version' , res.version) } else { if (res.version !== localStorage.getItem( 'demo_version' )) { localStorage.setItem( 'demo_version' , res.version) Modal.confirm({ title: '检测到新版本,是否更新?' , content: '新版本内容:' + res.content, okText: '更新' , cancelText: '取消' , onOk: () => { window.location.reload() }, }) } } } onMounted(()=>{ clearInterval(timer.value) timer.value = setInterval(async () => { checkUpdate() }, 30000) }) |
Use
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // vite.config.ts import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import { webUpdateNotice } from '@plugin-web-update-notification/vite' // https://vitejs.dev/config/ export default defineConfig({ plugins: [ vue(), webUpdateNotice({ logVersion: true , }), ] }) |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)
2023-11-29 记录--闭包,沙箱,防抖节流,函数柯里化,数据劫持......
2022-11-29 记录--两行CSS让页面提升了近7倍渲染性能!