稀土掘金技术社区 01月28日
前端如何优雅通知用户刷新页面?
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文探讨了前端SPA应用更新时用户体验不佳的问题,如用户需手动刷新才能看到新页面或接口报错。文章提出了三种解决方案:前后端配合的WebSocket/SSE、纯前端轮询html Etag/Last-Modified以及利用versionData.json自定义插件。重点介绍了后两种方案,包括代码实现和原理。轮询方案通过比对Etag或Last-Modified实现版本检测,自定义插件则生成versionData.json文件,通过比对版本号实现更新提示。此外,还提及了plugin-web-update-notification插件的使用,旨在提升用户体验。

🤔 针对SPA应用更新后用户无法立即看到新页面、可能导致接口报错等问题,文章提出了优化用户体验的必要性。

🔄 纯前端解决方案,如轮询html的Etag/Last-Modified,通过定时请求比对Etag值,检测到更新后提示用户刷新页面,代码示例详细展示了如何在Vue3项目中实现。

🛠️ 自定义插件方案,利用vite插件在构建时生成versionData.json文件,前端定时请求该文件,比对版本号来判断是否需要更新,并弹出更新提示,提供了更灵活的更新控制。

📦 文章还简单介绍了plugin-web-update-notification插件的使用,它能帮助开发者更便捷地实现Web应用更新通知的功能,提升用户体验。

原创 李暖阳啊 2025-01-27 08:31 重庆

点击关注公众号,“技术干货” 及时达!

前言

老板:新的需求不是上线了嘛,怎么用户看到的还是老的页面呀
窝囊废:让用户刷新一下页面,或者清一下缓存
老板:那我得告诉用户,刷新一下页面,或者清一下缓存,才能看到新的页面呀,感觉用户体验不好啊,不能直接刷新页面嘛?
窝囊废:可以解决(OS:一点改的必要没有,用户全是大聪明)

产品介绍

c端需要经常进行一些文案调整,一些老版的文字字眼可能会导致一些舆论问题,所以就需要更新之后刷新页面,让用户看到新的页面。

思考问题为什么产生

项目是基于vue的spa应用,通过nginx代理静态资源,配置了index.html协商缓存,js、css等静态文件Cache-Control,按正常前端重新部署后,用户重新访问系统,已经是最新的页面。

但是绝大部份用户都是访问页面之后一直停留在此页面,这时候前端部署后,用户就无法看到新的页面,需要用户刷新页面。

产生问题

解决方案

    前后端配合解决

    纯前端方案以下示例均以vite+vue3为例;

在App.vue中添加如下代码

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);

自定义plugin,项目根目录创建/plugins/vitePluginCheckVersion.ts

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中引入插件

import { checkVersion } from "./plugins/vitePluginCheckVersion";plugins: [  vue(),  checkVersion(),]

在App.vue中添加如下代码

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

// vite.config.tsimport { 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, }), ]})

点击关注公众号,“技术干货” 及时达!

阅读原文

跳转微信打开

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

SPA应用 前端更新 用户体验 Vite插件 版本控制
相关文章