当前位置: 首页 > news >正文

网页判断版本更新

一、需求解析

为什么我会想到这个技术呢,是因为我有一次发现,我司的用户在使用网页的时候,经常会出现一个页面放很久,下班也不关这个页面,这样就会导致页面的代码长时间处于不更新的状态。
在使用到一个功能出了bug,或者逻辑已经改变的情况报错了,过来问我们为什么会报错,我们花时间排查之后,发现是因为代码没更新。其实这种错误完全是可以避免的,我们要如何提醒用户:代码已经更新了,请更新版本呢?

二、需求思考过程

  1. 首先,要达到让用户知道版本更新,肯定需要弹出一个窗口,提示用户版本更新,请保存当前的工作内容,并点击更新按钮,进行更新操作。在这里插入图片描述
  2. 我们如何去设置每次发版的代码版本呢?
  3. 代码版本发布后,我们又要如何检测到版本发生变化呢?

三、难题解决

设置每次发版的代码版本

因为我比较少写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";}
}

相关文章:

网页判断版本更新

一、需求解析 为什么我会想到这个技术呢&#xff0c;是因为我有一次发现&#xff0c;我司的用户在使用网页的时候&#xff0c;经常会出现一个页面放很久&#xff0c;下班也不关这个页面&#xff0c;这样就会导致页面的代码长时间处于不更新的状态。 在使用到一个功能出了bug&a…...

ros1 基础学习08- 实现Server端自定义四 Topic模式控制海龟运动

一、服务模型 Server端本身是进行模拟海龟运动的命令端&#xff0c;它的实现是通过给海龟发送速度&#xff08;Twist&#xff09;的指令&#xff0c;来控制海龟运动&#xff08;本身通过Topic实现&#xff09;。 Client端相当于海龟运动的开关&#xff0c;其发布Request来控制…...

面试题之TCP粘包现象及其解决方法

计算机网络每层的基本单位&#xff1a;物理层&#xff08;第一层&#xff09;&#xff1a;比特流&#xff1b;数据链路层&#xff08;第二层&#xff09;&#xff1a;数据帧&#xff1b;网络层&#xff08;第三层&#xff09;&#xff1a;数据包&#xff1b;传输层&#xff08;…...

Word 插入的 Visio 图片显示为{EMBED Visio.Drawing.11} 解决方案

World中&#xff0c;如果我们插入了Visio图还用了Endnote&#xff0c; 就可能出现&#xff1a;{EMBED Visio.Drawing.11}问题 解决方案&#xff1a; 1.在相应的文字上右击&#xff0c;在出现的快捷菜单中单击“切换域代码”&#xff0c;一个一个的修复。 2.在菜单工具–>…...

Elasticsearch倒排索引、索引操作、映射管理

一、倒排索引 1、倒排索引是什么 倒排索引源于实际应用中需要根据属性的值来查找记录,这种索引表中的每一个项都包括一个属性值和具有该属性值的各记录的地址。由于不是由记录来确定属性值,而是由属性值来确定记录的位置,因而成为倒排索引。带有倒排索引的文件我们称之为倒…...

USEFUL PHRASES

THINGS YOU LIKE Q&#xff1a;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库&#xff0c;提供多维数组对象&#xff0c;各种派生对象&#xff08;如掩码数组和矩阵&#xff09;&#xff0c;以及用于数组快速操作的各种API&#xff0c;有包括数学、逻辑、形状操作、排序、选择、输入输出、离散傅立叶变…...

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.判断一个表是否是环形链表&#xff01; 代码如下 解析如下 2.快指针的步数和慢指针的步数有什么影响&#xff08;无图解析&#xff09; 3.怎么找到环形链表的入环点 代码如下 解析如下 1.判断一个表是否是环形链表&#xff01; 代码如下 bool hasCycle(struct L…...

科技云报道:数智化升级,如何跨越数字世界与实体产业的鸿沟?

科技云报道原创。 数智化是当下商业环境下最大的确定性。 2022年&#xff0c;中国数字经济规模达50.2万亿元&#xff0c;占国内生产总值比重提升至41.5%&#xff0c;数字经济成为推动经济发展的重要引擎。从小型创业公司到跨国巨头&#xff0c;数字化转型在企业发展历程中彰显…...

Rt-Thread 移植6--多线程(KF32)

6.1 就绪列表 6.1.1 线程就绪优先级组 线程优先级表的索引对应的线程的优先级。 为了快速的找到线程在线程优先级表的插入和移出的位置&#xff0c;RT-Thread专门设计了一个线程就绪优先级组。线程就绪优先组是一个32位的整型数&#xff0c;每一个位对应一个优先级&#xff…...

HarmonyOS应用开发-首选项与后台通知管理

首选项 在移动互联网蓬勃发展的今天&#xff0c;移动应用给我们生活带来了极大的便利&#xff0c;这些便利的本质在于数据的互联互通。因此在应用的开发中数据存储占据了非常重要的位置&#xff0c;HarmonyOS应用开发也不例外。本章以HarmonyOS的首选项为例&#xff0c;介绍了…...

通过easyexcel导出数据到excel表格

这篇文章简单介绍一下怎么通过easyexcel做数据的导出&#xff0c;使用之前easyui构建的歌曲列表crud应用&#xff0c;添加一个导出按钮&#xff0c;点击的时候直接连接后端接口地址&#xff0c;在后端的接口完成数据的导出功能。 前端页面完整代码 let editingId; let request…...

Android---MVP 中 presenter 声明周期的管理

我们经常在 Android MVP 架构中的 Presenter 层做一些耗时操作&#xff0c;比如请求网络数据&#xff0c;然后根据请求后的结果刷新 View。但是&#xff0c;如果按返回结束 Activity&#xff0c;而 Presenter 依然在执行耗时操作。那么就有可能造成内存泄漏&#xff0c;严重时甚…...

Oracle中的索引碎片

索引碎片是指索引在存储空间上不连续的分布情况&#xff0c;它可能会影响到数据库性能和查询效率。索引碎片化主要由以下几个原因导致&#xff1a; 插入、更新和删除操作&#xff1a;当对表中的数据进行插入、更新或删除操作时&#xff0c;索引也需要相应地更新。这些DML操作可…...

Java必刷入门递归题×5(内附详细递归解析图)

目录 1.求N的阶乘 2.求12...N的和 3.顺序打印数字的每一位 4.求数字的每一位之和 5.求斐波拉契数列 1.求N的阶乘 &#xff08;1&#xff09;解析题目意思 比如求5的阶乘&#xff0c;符号表示就是5&#xff01;&#xff1b;所以5&#xff01;5*4*3*2*1我们下面使用简单的…...

android 闪屏图适配尺寸

不同的 Android 设备可能具有不同的屏幕尺寸和分辨率&#xff0c;因此最好提供不同尺寸的启动画面图像&#xff0c;以确保与各种设备的兼容性。 以下是 Android 启动画面图像的一些最常见尺寸&#xff1a; 320 x 480像素&#xff08;肖像&#xff09; 480 x 320像素&#xff0…...

AI Agent在游戏NPC中的革命:从脚本行为到自主人格生成

AI Agent在游戏NPC中的革命:从脚本行为到自主人格生成 关键词:AI Agent、游戏NPC、脚本行为、自主人格、行为树、大语言模型、游戏开发 摘要:本文将深入探讨AI Agent技术如何革命性地改变游戏NPC的设计与实现。我们将从传统的脚本行为开始,一步步演进到基于大语言模型的自主…...

AI编程新选择:OpenCode集成Qwen3-4B模型,终端原生体验快速上手

AI编程新选择&#xff1a;OpenCode集成Qwen3-4B模型&#xff0c;终端原生体验快速上手 1. 引言&#xff1a;为什么选择OpenCode&#xff1f; 在AI编程助手领域&#xff0c;开发者常常面临三个核心痛点&#xff1a;模型切换不灵活、隐私安全顾虑、以及终端体验割裂。OpenCode的…...

Vue + G 实战:打造高校学生打卡数据可视化大屏米

1、普通的insert into 如果&#xff08;主键/唯一建&#xff09;存在&#xff0c;则会报错 新需求&#xff1a;就算冲突也不报错&#xff0c;用其他处理逻辑 回到顶部 2、基本语法&#xff08;INSERT INTO ... ON CONFLICT (...) DO (UPDATE SET ...)/(NOTHING)&#xff09; 语…...

加密货币钱包原理与开发

加密货币钱包原理与开发&#xff1a;数字资产的安全之门 在区块链技术蓬勃发展的今天&#xff0c;加密货币钱包作为管理数字资产的核心工具&#xff0c;已成为用户进入加密世界的必备钥匙。无论是比特币、以太坊还是其他代币&#xff0c;钱包不仅存储密钥&#xff0c;更是实现…...

【大模型工程化评估黄金标准】:20年AI架构师首次公开7大核心指标与落地避坑指南

第一章&#xff1a;大模型工程化评估指标体系构建指南 2026奇点智能技术大会(https://ml-summit.org) 构建面向生产环境的大模型评估指标体系&#xff0c;需兼顾模型能力、系统性能、业务适配性与合规可持续性四大维度。脱离工程落地场景的纯学术指标&#xff08;如零样本准确…...

避坑指南:YooAsset整合HybridCLR时,如何正确处理AOT与热更DLL的打包与加载?

YooAsset与HybridCLR深度整合&#xff1a;AOT与热更DLL的打包加载全解析 当Unity开发者尝试将YooAsset的资源热更新能力与HybridCLR的代码热更新功能结合时&#xff0c;往往会遇到各种"陷阱"。其中最典型的莫过于&#xff1a;明明按照文档将DLL转为.bytes文件&#x…...

TMC4671电机驱动调试避坑指南:从SPI通信失败到电机抖动的实战排查

TMC4671电机驱动调试避坑指南&#xff1a;从SPI通信失败到电机抖动的实战排查 调试TMC4671电机驱动芯片时&#xff0c;工程师常会遇到各种"坑"和"雷区"。本文将聚焦实际调试过程中最常见的问题&#xff0c;提供一套从现象到原因的逆向排查方法&#xff0c;…...

MeteorSeed繁

这个代码的核心功能是&#xff1a;基于输入词的长度动态选择反义词示例&#xff0c;并调用大模型生成反义词&#xff0c;体现了 “动态少样本提示&#xff08;Dynamic Few-Shot Prompting&#xff09;” 与 “上下文长度感知的示例选择” 的能力。 from langchain.prompts impo…...

VideoAgentTrek Screen Filter开发指南:使用Git进行版本管理与协作

VideoAgentTrek Screen Filter开发指南&#xff1a;使用Git进行版本管理与协作 如果你正在基于VideoAgentTrek Screen Filter进行二次开发&#xff0c;无论是修改AI模型推理逻辑&#xff0c;还是调整视频过滤规则&#xff0c;很快你就会遇到一个现实问题&#xff1a;代码怎么管…...

工业图像异常检测新思路:手把手教你用DDAD模型定位缺陷(附代码实战)

工业图像异常检测实战&#xff1a;基于DDAD模型的缺陷定位全流程解析 在工业质检领域&#xff0c;图像异常检测技术正经历着从传统算法到深度学习的范式转变。传统方法往往受限于特征提取能力和复杂背景干扰&#xff0c;而基于生成模型的解决方案正在重新定义检测精度与适用边界…...