网页判断版本更新
一、需求解析
为什么我会想到这个技术呢,是因为我有一次发现,我司的用户在使用网页的时候,经常会出现一个页面放很久,下班也不关这个页面,这样就会导致页面的代码长时间处于不更新的状态。
在使用到一个功能出了bug,或者逻辑已经改变的情况报错了,过来问我们为什么会报错,我们花时间排查之后,发现是因为代码没更新。其实这种错误完全是可以避免的,我们要如何提醒用户:代码已经更新了,请更新版本呢?
二、需求思考过程
- 首先,要达到让用户知道版本更新,肯定需要弹出一个窗口,提示用户版本更新,请保存当前的工作内容,并点击更新按钮,进行更新操作。

- 我们如何去设置每次发版的代码版本呢?
- 代码版本发布后,我们又要如何检测到版本发生变化呢?
三、难题解决
设置每次发版的代码版本
因为我比较少写jquery 等其他技术的前端,在此就针对 vue react 等工程化的前端技术栈进行解析
每次我们在发布版本,都会走一个步骤,那就是 npm run build打包操作
我们需要在打包的时候给打包后的代码加上一个版本号,我目前能想到两个方式实现: 文件更新后的hash值 和 index.html 里面的 meta
简单说一下 hash值,打包的设置那里,我们可以设置每次打包后,文件的hash值变动,只有有一个hash值变了,那么我们就可以理解为版本更新了,但是这个我用的比较少,在此做一个截图举例即可
以下着重介绍通过判断 index.html 的 meta去判断版本更新的方式
我们可以写一个node脚本,在npm run build命令之后,执行这个node脚本,往我们打包后的dist文件夹里面的 index.html 文件插入一个 meta,里面是我们的版本号,脚本如下:
const fs = require('fs')/**版本号,当前时间戳,保证唯一 */
const versionNo = new Date().getTime()
const htmlPath = './dist/index.html'const insertVersionMeta = () => {let html = fs.readFileSync(htmlPath, 'utf-8')html = html.replace('<head>', `<head><meta name="version_no" content="${versionNo}" />`)fs.writeFileSync(htmlPath, html)
}insertVersionMeta()
以上代码的逻辑就是,获取到打包后的dist/index.html 文件,通过fs.readFileSync去读取到里面的内容,然后往 head 里面插入一个 meta,说明当前网页的版本号,我这里用的是最简单的时间戳
如果想要达成我们想象中的 v1.0.0这种 x-y-z 的版本格式,可以运行这个脚本的时候,弹出像vue脚手架创建那种命令行输入的方式,如
1-请问您本次版本更新是:
a.小版本更新(自动更新z+1)
b.大需求更新(自动y+1)
c. 超大版本更新,颠覆页面等这种(自动 x+1)
d. 自己输入版本号
2-请简单描述一下本次版本更新的内容:
要达到这种效果,就得加入
inquirer等命令行的开源技术,如果感兴趣,我也可以后续对这个脚本进行优化,加入这个效果。在此就先不展开
检测代码版本是否更新
检测是否更新,我们只需要获取远程服务器的index.html 文件,获取到里面我们设置好的 version_no ,与我们当前网页的 version_no 做对比,只要存在不同,那么就代表版本更新了。在此我采用一个轮询的方式进行编写,如果是已经引入webSocket项目,也可以采用socket的方式进行通知
// App.vue
data() {return {// 轮询查询新版本timer: null,pollingTime: 1000 * 60 * 30 // 半小时},
created() {this.getCurrentVersion()this.fetchNewVersion()this.timer = setInterval(() => {this.fetchNewVersion()}, this.pollingTime)},
methods: {// 获取当前版本号getCurrentVersion() {const metaList = document.querySelectorAll('meta')if (!metaList.length) returnfor (let i = 0; i < metaList.length; i++) {const item = metaList[i]if (item.name === 'version_no') {this.version = item.contentbreak}}},// 获取远程服务器的版本号async fetchNewVersion() {// 在 js 中请求首页地址不会更新页面const timestamp = new Date().getTime()const response = await axios.get(`${window.location.origin}?time=${timestamp}`)// 返回的是字符串,需要转换为 htmlconst el = document.createElement('html')el.innerHTML = response.datalet newVersion = ''// 拿到版本号const metaList = el.querySelectorAll('meta')if (!metaList.length) returnfor (let i = 0; i < metaList.length; i++) {const item = metaList[i]if (item.name === 'version_no') {newVersion = item.contentbreak}}if (newVersion && newVersion !== this.version) {this.$refs['NoticeNewVersion'].open()}},
}
}
弹窗版本更新通知
这一块就很简单了,我们只需要写一个版本更新的组件,让它弹出,版本号 和 版本说明,直接获取远程服务器的meta显示即可。
四、遇到的坑
我写好这个后,发现一个问题:每次弹出版本更新通知,过了一会儿后会再次弹出,但我并没有再次部署版本,而且这个问题不是必现的,有的人是好的,有的人会一直弹出
后面发现,原来是缓存的锅,刷新后,浏览器存在html的缓存304,导致一直获取到是老的版本号,那么每次轮询都会弹出版本更新。
如何解决呢:只需要在nginx里面,设置index.html不缓存即可
location / {expires 1h;root /home/html;index index.html index.htm;## html不缓存 if ($request_filename ~* .*\.(htm|html)$) {add_header Cache-Control "no-store";}
}
相关文章:
网页判断版本更新
一、需求解析 为什么我会想到这个技术呢,是因为我有一次发现,我司的用户在使用网页的时候,经常会出现一个页面放很久,下班也不关这个页面,这样就会导致页面的代码长时间处于不更新的状态。 在使用到一个功能出了bug&a…...
ros1 基础学习08- 实现Server端自定义四 Topic模式控制海龟运动
一、服务模型 Server端本身是进行模拟海龟运动的命令端,它的实现是通过给海龟发送速度(Twist)的指令,来控制海龟运动(本身通过Topic实现)。 Client端相当于海龟运动的开关,其发布Request来控制…...
面试题之TCP粘包现象及其解决方法
计算机网络每层的基本单位:物理层(第一层):比特流;数据链路层(第二层):数据帧;网络层(第三层):数据包;传输层(…...
Word 插入的 Visio 图片显示为{EMBED Visio.Drawing.11} 解决方案
World中,如果我们插入了Visio图还用了Endnote, 就可能出现:{EMBED Visio.Drawing.11}问题 解决方案: 1.在相应的文字上右击,在出现的快捷菜单中单击“切换域代码”,一个一个的修复。 2.在菜单工具–>…...
Elasticsearch倒排索引、索引操作、映射管理
一、倒排索引 1、倒排索引是什么 倒排索引源于实际应用中需要根据属性的值来查找记录,这种索引表中的每一个项都包括一个属性值和具有该属性值的各记录的地址。由于不是由记录来确定属性值,而是由属性值来确定记录的位置,因而成为倒排索引。带有倒排索引的文件我们称之为倒…...
USEFUL PHRASES
THINGS YOU LIKE Q:Do you like social science? Yes, I can’t get enough of it.Yes, what I like most about it is it’s so interesting, for example, last week I read an article about solar panels and how we use them to protect the planet.Yes, I lo…...
【OpenCV】 拟合直线 与 霍夫直线 对比 , fitLine()与 HoughLinesP()对比
文章目录 1 fitLine 与 HoughLinesP 函数原型2 拟合直线 与 霍夫直线 对比拟合线和圆,是通过已知点拟合出对应的方程,拟合方法如最小二乘法,RANSAC算法等。如果拟合点的离散成都较高,拟合方法的正确选择,是提高识别精度的一大要点。 1 fitLine 与 HoughLinesP 函数原型 …...
Python与ArcGIS系列(六)查找和修复数据源
目录 0 简述1 查找丢失数据源2 findAndReplaceWorkspacePaths()方法修复丢失数据源3 replaceWorkspaces()方法修复丢失数据源4 replaceDataSource()修复单个图层和表对象0 简述 当对数据源进行移动、转换和删除时都会导致数据源丢失链接问题,无法正常显示地图数据。对于多个数…...
聊聊logback的TimeBasedRollingPolicy
序 本文主要研究一下logback的TimeBasedRollingPolicy TimeBasedRollingPolicy public class TimeBasedRollingPolicy<E> extends RollingPolicyBase implements TriggeringPolicy<E> {static final String FNP_NOT_SET "The FileNamePattern option must…...
numpy 基础使用
NumPy是Python中科学计算的基础包。它是一个Python库,提供多维数组对象,各种派生对象(如掩码数组和矩阵),以及用于数组快速操作的各种API,有包括数学、逻辑、形状操作、排序、选择、输入输出、离散傅立叶变…...
sqlite3编译脚本
../configure --hostarm --buildx86 CC/opt/sdk/gcc-arm-8.3-arm-armv5t-linux-gnueabi/bin/arm-armv5t-linux-gnueabi-gcc --prefix/opt/sdk/gcc-arm-8.3-arm-armv5t-linux-gnueabi/arm-armv5t-linux-gnueabi/sysroot/usr...
环形链表解析(c语言)c语言版本!自我解析(看了必会)
目录 1.判断一个表是否是环形链表! 代码如下 解析如下 2.快指针的步数和慢指针的步数有什么影响(无图解析) 3.怎么找到环形链表的入环点 代码如下 解析如下 1.判断一个表是否是环形链表! 代码如下 bool hasCycle(struct L…...
科技云报道:数智化升级,如何跨越数字世界与实体产业的鸿沟?
科技云报道原创。 数智化是当下商业环境下最大的确定性。 2022年,中国数字经济规模达50.2万亿元,占国内生产总值比重提升至41.5%,数字经济成为推动经济发展的重要引擎。从小型创业公司到跨国巨头,数字化转型在企业发展历程中彰显…...
Rt-Thread 移植6--多线程(KF32)
6.1 就绪列表 6.1.1 线程就绪优先级组 线程优先级表的索引对应的线程的优先级。 为了快速的找到线程在线程优先级表的插入和移出的位置,RT-Thread专门设计了一个线程就绪优先级组。线程就绪优先组是一个32位的整型数,每一个位对应一个优先级ÿ…...
HarmonyOS应用开发-首选项与后台通知管理
首选项 在移动互联网蓬勃发展的今天,移动应用给我们生活带来了极大的便利,这些便利的本质在于数据的互联互通。因此在应用的开发中数据存储占据了非常重要的位置,HarmonyOS应用开发也不例外。本章以HarmonyOS的首选项为例,介绍了…...
通过easyexcel导出数据到excel表格
这篇文章简单介绍一下怎么通过easyexcel做数据的导出,使用之前easyui构建的歌曲列表crud应用,添加一个导出按钮,点击的时候直接连接后端接口地址,在后端的接口完成数据的导出功能。 前端页面完整代码 let editingId; let request…...
Android---MVP 中 presenter 声明周期的管理
我们经常在 Android MVP 架构中的 Presenter 层做一些耗时操作,比如请求网络数据,然后根据请求后的结果刷新 View。但是,如果按返回结束 Activity,而 Presenter 依然在执行耗时操作。那么就有可能造成内存泄漏,严重时甚…...
Oracle中的索引碎片
索引碎片是指索引在存储空间上不连续的分布情况,它可能会影响到数据库性能和查询效率。索引碎片化主要由以下几个原因导致: 插入、更新和删除操作:当对表中的数据进行插入、更新或删除操作时,索引也需要相应地更新。这些DML操作可…...
Java必刷入门递归题×5(内附详细递归解析图)
目录 1.求N的阶乘 2.求12...N的和 3.顺序打印数字的每一位 4.求数字的每一位之和 5.求斐波拉契数列 1.求N的阶乘 (1)解析题目意思 比如求5的阶乘,符号表示就是5!;所以5!5*4*3*2*1我们下面使用简单的…...
android 闪屏图适配尺寸
不同的 Android 设备可能具有不同的屏幕尺寸和分辨率,因此最好提供不同尺寸的启动画面图像,以确保与各种设备的兼容性。 以下是 Android 启动画面图像的一些最常见尺寸: 320 x 480像素(肖像) 480 x 320像素࿰…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
【iOS】 Block再学习
iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...
