纯前端实现更新检测

通过判断打包后的html文件中的js入口是否发生变化,进而实现前端的代码更新

为了使打包后的文件带有hash值,需要对vite打包进行配置

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'export default defineConfig({base: './',plugins: [vue(), AutoImport({resolvers: [ElementPlusResolver()],}),Components({resolvers: [ElementPlusResolver()],}),],envDir: './', // .env所在目录build: {target: 'es2015',outDir: 'dist',rollupOptions: {output: {manualChunks(id) { if (id.includes('node_modules')) {return id.toString().split('node_modules/')[1].split('/')[0].toString();}},// 文件附带上hashentryFileNames: '[name]-[hash].js',chunkFileNames: '[name]-[hash].js',assetFileNames: '[name]-[hash].[ext]'}},minify: 'esbuild', },resolve: {alias: {"@": resolve(__dirname, 'src'),},extensions: ['.vue', '.js']},server: {proxy: {'/api': {target: 'http://localhost:8083',changeOrigin: true,rewrite: (path) => path.replace(/^\/api/, "")}}},
});

update.js的主要功能是定期检查网页中的脚本标签是否有更新,并在检测到新版本时提示用户刷新页面以确保平台正常使用。

// update.js
import { ElMessageBox } from 'element-plus';let timer = undefined;
const url = import.meta.env.VITE_UPDATE_URL;function cmpSets(set1, set2) {if (set1.size !== set2.size) return false;for (let item of set1) {if (!set2.has(item)) return false;}return true;
}
// 更新提示框
function updateNotice() {ElMessageBox({title: '更新提示!',message: "检测到新版本,请立即刷新以确保平台正常使用",confirmButtonText: '确定',type: 'warning',}).finally(() => {window.location.reload();});
}// 获取页面中的脚本标签src属性的哈希值集合,忽略查询参数
async function getSrcHash() {try {const html = await fetch(url).then((res) => res.text());const scriptSrcRegex = /<script\b[^>]*src="([^"]*)"/gi;const scriptSrcs = [...html.matchAll(scriptSrcRegex)].map(match => match[1]);// 开发环境中入口文件包含保存时的时间戳,判断时移除此参数以免开发时一直提示更新const cleanSrcs = scriptSrcs.map(src => src.split('?')[0]); const encodedSrcs = new Set(cleanSrcs.map(src => encodeURIComponent(src)));return encodedSrcs;} catch (error) {console.error('Failed to fetch script hashes:', error);return new Set();}
}// 比较当前脚本标签哈希值与新获取的哈希值
async function cmpHash() {try {const newHash = await getSrcHash();const storedHash = JSON.parse(localStorage.getItem('curHash')) || [];// 如果是新用户或首次访问,直接保存哈希值并退出函数if (storedHash.length === 0) {localStorage.setItem('curHash', JSON.stringify([...newHash]));return;}// 合并新旧哈希值集合let curHash = new Set(storedHash);if (!cmpSets(curHash, newHash)) {console.info("new:", newHash);console.info("old:", curHash);console.log("更新提示")clearInterval(timer);updateNotice();}// 保存最新的哈希值集合到localStoragelocalStorage.setItem('curHash', JSON.stringify([...newHash]));} catch (error) {console.error('Error comparing script hashes:', error);}
}// 设置定时器,定期检查脚本更新
timer = setInterval(cmpHash, 30 * 1000);// 页面加载时比较哈希值
async function init() {await cmpHash();
}
// 页面加载时执行初始化函数
init();

最后在main.js入口文件引入即可

import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import router from './router/index.ts'
import "./update.js" //引入自动更新脚本
import { createPinia } from 'pinia'const pinia = createPinia()
const app = createApp(App)
app.use(router)
app.use(pinia)
app.use(ElementPlus)
app.mount('#app')

通过篡改localstorage中的curHash,可引导更新,效果如下

30s更新一次算频繁吗?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/493135.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

arcgisPro相接多个面要素转出为完整独立线要素

1、使用【面转线】工具&#xff0c;并取消勾选“识别和存储面邻域信息”&#xff0c;如下&#xff1a; 2、得到的线要素&#xff0c;如下&#xff1a;

基于SpringBoot+html+vue实现的林业产品推荐系统【源码+文档+数据库文件+包部署成功+答疑解惑问到会为止】

代码包运行启动成功&#xff01;不管你有没有运行环境&#xff0c;哪怕你是刚买的新电脑&#xff0c;也包启动运行成功&#xff01;有不懂的地方随便问&#xff01;问到会为止&#xff01; 【功能介绍】 基于SpringBootVue实现的林业产品推荐系统采用前后端分离的架构方式&…

【Java基础面试题024】Java中包装类型和基本类型的区别是什么?

回答重点 基本类型&#xff1a; Java中有8种基本数据类型&#xff08;byte、short、int、long、float、double、char、boolean&#xff09;他们是直接存储数值的变量&#xff0c;位于栈上&#xff08;局部变量在栈上、成员变量在堆上&#xff0c;静态字段/类在方法区&#xf…

.net core在linux导出excel,System.Drawing.Common is not supported on this platform

使用框架 .NET7 导出组件 Aspose.Cells for .NET 5.3.1 asp.net core mvc 如果使用Aspose.Cells导出excel时&#xff0c;报错 &#xff1a; System.Drawing.Common is not supported on this platform 平台特定实现&#xff1a; 对于Windows平台&#xff0c;System.Drawing.C…

web自动化测试知识总结

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、自动化测试基本介绍 1、自动化测试概述&#xff1a; 什么是自动化测试&#xff1f;一般说来所有能替代人工测试的方式都属于自动化测试&#xff0c;即通过工…

怿星科技联合赛力斯举办workshop活动,进一步推动双方合作

12月18日&#xff0c;由怿星科技与赛力斯汽车联合举办的workshop活动在赛力斯五云湖总部展开&#xff0c;双方嘉宾围绕智能汽车发展趋势、行业前沿技术、汽车电子网络与功能测试等核心议题展开了深度对话与交流&#xff0c;并现场参观演示了多套前沿产品。怿星科技CEO潘凯、汽车…

【Flutter_Web】Flutter编译Web第二篇(webview篇):flutter_inappwebview如何改造方法,变成web之后数据如何交互

前言 欢迎来到第二篇文章&#xff0c;这也是第二个难题&#xff0c;就是原有的移动端本身一些页面H5的形式去呈现&#xff08;webview&#xff09;&#xff0c;例如某些需要动态更换内容的页面&#xff0c;某些活动页面、支付页面&#xff0c;不仅仅做页面呈现&#xff0c;还包…

JS信息收集(小迪网络安全笔记~

免责声明&#xff1a;本文章仅用于交流学习&#xff0c;因文章内容而产生的任何违法&未授权行为&#xff0c;与文章作者无关&#xff01;&#xff01;&#xff01; 附&#xff1a;完整笔记目录~ ps&#xff1a;本人小白&#xff0c;笔记均在个人理解基础上整理&#xff0c;…

基于w25q128的智能门禁

项目需求 1. 矩阵键盘输入密码&#xff0c;正确则开锁&#xff0c;错误则提示&#xff0c;三次错误蜂鸣器响3秒&#xff1b; 2. 按下#号确认输入&#xff0c;按下*号修改密码&#xff1b; 3. 密码保存在 W25Q128 里&#xff1b; 4. OLED 屏幕显示信息。

【计算机网络】期末考试预习复习|中

作业讲解 转发器、网桥、路由器和网关(4-6) 作为中间设备&#xff0c;转发器、网桥、路由器和网关有何区别&#xff1f; (1) 物理层使用的中间设备叫做转发器(repeater)。 (2) 数据链路层使用的中间设备叫做网桥或桥接器(bridge)。 (3) 网络层使用的中间设备叫做路…

开放词汇目标检测(Open-Vocabulary Object Detection, OVOD)综述

定义 开放词汇目标检测&#xff08;Open-Vocabulary Object Detection, OVOD&#xff09;是一种目标检测任务&#xff0c;旨在检测和识别那些未在训练集中明确标注的物体类别。传统的目标检测模型通常只能识别有限数量的预定义类别&#xff0c;而OVOD模型则具有识别“开放词汇…

单点登录平台Casdoor搭建与使用,集成gitlab同步创建删除账号

一&#xff0c;简介 一般来说&#xff0c;公司有很多系统使用&#xff0c;为了实现统一的用户名管理和登录所有系统&#xff08;如 GitLab、Harbor 等&#xff09;&#xff0c;并在员工离职时只需删除一个主账号即可实现权限清除&#xff0c;可以采用 单点登录 (SSO) 和 集中式…

算法笔记—前缀和(动态规划)

【模板】前缀和_牛客题霸_牛客网 (nowcoder.com) #include <initializer_list> #include <iostream> #include <vector> using namespace std;int main() {//输入数据int n,q;cin>>n>>q;vector<int> arr;arr.resize(n1);for(int i1;i<…

力扣438-找到字符串中所有字母异位词

力扣438-找到字符串中所有字母异位词 力扣438-找到字符串中所有字母异位词原题地址&#xff1a;https://leetcode.cn/problems/find-all-anagrams-in-a-string/description/ 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词的子串&#x…

linux-----进程及基本操作

进程的基本概念 定义&#xff1a;在Linux系统中&#xff0c;进程是正在执行的一个程序实例&#xff0c;它是资源分配和调度的基本单位。每个进程都有自己独立的地址空间、数据段、代码段、栈以及一组系统资源&#xff08;如文件描述符、内存等&#xff09;。进程的组成部分&am…

胡九道:经典传承(贵宾酒)

胡九道的由来 在辽阔的科尔沁草原上&#xff0c;有一个美丽的女子&#xff0c;她才貌双全&#xff0c;知书达礼&#xff0c;她就是历史上著名的孝庄皇后。大玉儿不仅聪慧过人&#xff0c;而且深具母仪天下的气质&#xff0c;深受百姓和皇室的敬爱。当她跟随丈夫皇太极入关来到…

【Mongo工具】Mongo迁移工具之Mongo-shake

Mongo-Shake 简介 Mongo-Shake 是一个基于 MongoDB 操作日志&#xff08;oplog&#xff09;的通用服务平台。它从源 MongoDB 数据库中获取操作日志&#xff0c;并在目标 MongoDB 数据库中重放&#xff0c;或者通过不同的隧道发送到其他终端。如果目标端是 MongoDB 数据库&…

EGO Swarm翻译

目录 摘要 Ⅰ 介绍 Ⅱ 相关工作 A . 单四旋翼局部规划 B . 拓扑规划 C. 分布式无人机集群 Ⅲ 基于梯度的局部规划隐式拓扑轨迹生成 A.无需ESDF梯度的局部路径规划 B.隐式拓扑轨迹生成 Ⅳ 无人机集群导航 A 机间避碰 B. 定位漂移补偿 C. 从深度图像中去除agent Ⅴ …

虚拟机断网没有网络,需清理内存,删除后再重启

进入NetworkManager可能没权限&#xff0c;设置权限777 to

整合 Knife4j 于 Spring Cloud 网关:实现跨服务的 API 文档统一展示

&#x1f3af;导读&#xff1a;本文档概述了构建和配置基于JDK 17、Spring Boot 3.0.7及Spring Cloud 2022.0.3的微服务系统&#xff0c;特别聚焦于集成Knife4j以增强API文档管理和接口测试功能。文中详细介绍了如何在Spring Boot应用中添加Knife4j依赖、配置Swagger UI路径和A…