记录—前端如何优雅通知用户刷新页面?

  • 记录—前端如何优雅通知用户刷新页面?已关闭评论
  • 19 次浏览
  • A+
所属分类:Web前端
摘要

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


🧑‍💻 写在开头

点赞 + 收藏 === 学会🤣🤣🤣

前言

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

产品介绍

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

思考问题为什么产生

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

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

产生问题

  • 如果后端接口有更新,前端重新部署后,用户访问老的页面,可能会导致接口报错。
  • 如果前端部署后,用户访问老的页面,可能无法看到新的页面,需要用户刷新页面,用户体验不好。
  • 出现线上bug,修复完后,用户依旧访问老的页面,仍会遇到bug。

解决方案

  1. 前后端配合解决
  • WebSocket
  • SSE(Server-Send-Event)
  1. 纯前端方案 以下示例均以vite+vue3为例;
  • 轮询html Etag/Last-Modified

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

  • versionData.json

自定义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.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,     }),   ] }) 

  

本文转载于:https://juejin.cn/post/7439905609312403483

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 记录---前端如何优雅通知用户刷新页面?