web项目版本更新检测与通知(两个解决方案)

发布日期:2025-08-26 02:02:56 分类:beat365官网在线体育 浏览:1233

背景:对于web项目常常出现的一个问题是:前端有新版本发布了,用户不能及时知晓,导致继续访问了可能有bug的旧版本。 目的:纯前端实现能够主动通知用户更新版本,确保用户能够及时获得最新的功能和修复的 bug。

此方案基本原理:打包的时候生成随机版本号并保存到环境变量里,在index.html的mate标签注入版本号。通过轮询获取index.html的版本号与本地版本号比较。此方案大部分是在前端实现(前提考虑的就是尽量不依赖服务端来实现),服务端要做的仅仅是配置服务器 不缓存index.html。(欢迎评论区交流、分享更多的方案实现~)

以Vue项目为例,具体实现如下:

vue.config.js:

process.env.VUE_APP_VERSION = Date.now() // 生成随机版本号,赋值到环境变量

index.html:

checkForUpdate.js: 开启轮询,定义通知样式

let currentVersion = null

let delay = process.env.VUE_APP_ENV === 'development' ? 6 * 1000 : 10 * 1000

function notifyUserAboutUpdate() {

const updateNotification = document.createElement('div')

updateNotification.innerText = '新版本已发布,请刷新页面以获取最新内容。'

updateNotification.style.position = 'fixed'

updateNotification.style.top = '-45px' // 初始位置在视口上方

updateNotification.style.width = '100%'

updateNotification.style.backgroundColor = 'rgba(248, 215, 218, 0.9)'

updateNotification.style.color = '#721c24'

updateNotification.style.textAlign = 'center'

updateNotification.style.height = '45px'

updateNotification.style.lineHeight = '45px'

updateNotification.style.zIndex = '9999'

updateNotification.style.transition = 'top 1s' // 设置过渡效果

// 定义左右抖动的CSS动画

const styleSheet = document.createElement('style')

styleSheet.type = 'text/css'

styleSheet.innerText = `

@keyframes shake {

0%, 100% { transform: translateX(0); }

25% { transform: translateX(-10px); }

50% { transform: translateX(10px); }

75% { transform: translateX(-10px); }

}

`

document.head.appendChild(styleSheet)

document.body.appendChild(updateNotification)

// 触发从顶部进入效果

setTimeout(() => {

updateNotification.style.top = '0'

}, 500)

// 1.5秒后开始左右抖动动画

setTimeout(() => {

updateNotification.style.animation = 'shake 1s linear infinite'

}, 1500)

// 3.5秒后移除抖动动画

setTimeout(() => {

updateNotification.style.animation = ''

}, 3500)

}

document.addEventListener('DOMContentLoaded', () => {

currentVersion = document

.querySelector('meta[name="version"]')

.getAttribute('content')

if (window.Worker) {

const worker = new Worker('/static/js/updateWorker.js')

worker.postMessage({ currentVersion, delay })

worker.onmessage = (event) => {

if (event.data === 'updateAvailable') {

notifyUserAboutUpdate()

}

}

} else {

console.error('Web Workers are not supported in this browser.')

}

})

updateWorker.js: 定义轮询。此示例使用Worker,避免阻塞主进程。

let currentVersion = null

let delay = null

self.onmessage = (event) => {

currentVersion = event.data.currentVersion

delay = event.data.delay

checkForUpdate()

}

function checkForUpdate() {

fetch('/index.html')

.then((response) => response.text())

.then((html) => {

const versionMatch = html.match(

/

)

if (versionMatch) {

const newVersion = versionMatch[1]

if (newVersion !== currentVersion) {

self.postMessage('updateAvailable')

} else {

setTimeout(() => {

checkForUpdate()

}, delay)

}

} else {

console.error('Version meta tag not found')

}

})

.catch((error) => console.error('Error checking for update:', error))

}

main.js:

import '@/utils/checkForUpdate' // 入口文件引入js

方案二:https://blog.csdn.net/m0_62332650/article/details/143716432