
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
version-polling
Advanced tools
一个用于实时检测 web 应用更新的 JavaScript 库
以下内容是通过 GitHub Copilot 生成的 😊
在现代 web 应用开发中,前端代码的更新频率较高,尤其是单页应用(SPA)。当应用发布新版本时,如何及时通知用户并引导其刷新页面以加载最新资源,成为了一个亟待解决的问题。version-polling 库应运而生,旨在提供一种简单高效的方式来检测前端应用的版本更新,并提示用户进行页面刷新。
用户在浏览器中打开某 web 应用(通常是后台管理系统)很长时间且未刷新页面时,如果应用有新功能添加或问题修复,用户可能无法及时知道有新版发布。这样会导致用户继续使用旧版,影响用户体验和数据准确性,甚至出现程序报错。
针对前端 web 单页应用(SPA)而设计
纯前端技术实现,使用简单无需后端支持
提供三种版本控制方式
1.使用HTTP ETag作为版本标识符
2.使用chunkHash作为版本标识符 v1.3.0
3.使用version.json 文件管理版本号 v1.3.0
支持 TypeScript
HTTP ETag作为版本标识符使用
HTTP ETag作为版本标识符来判断应用是否有更新。
HTTP ETag说明:每次请求index.html文件时,HTTP 响应头上会有一个 ETag 字段, 格式类似ETag: W/"0815"该字段的值是服务器资源的唯一标识符,通过比较前后两次请求的 Etag 字段值,可以判断资源是否发生变化,以这个为依据判断是否有更新。
缺点是HTTP ETag是由服务器生成的,前端不可控。
Web WorkerAPI 在浏览器后台轮询请求index.html文件,不会影响主线程运行。index.html文件,对比本地和请求响应头的 ETag 的字段值。chunkHash作为版本标识符使用
chunkHash作为版本标识符来判断应用是否有更新。
chunkHash说明:因为前端 spa 项目都是打包后再部署,这里以 vite 为例,打包产物 index.html 文件内容中会存在一个 script 标签,格式类似<script type="module" crossorigin src="/assets/index.065a65a6.js"></script>,其中index是 chunk 名称,后面的065a65a6是 chunk 哈希值,每次项目代码有改动再打包这里的chunkHash哈希值都会发生变化,以这个为依据判断是否有更新。
Web WorkerAPI 在浏览器后台轮询请求index.html文件,不会影响主线程运行。index.html文件,对比当前文件和最新文件中的chunkHash的哈希值。chunkHash哈希值不一致,说明有更新,则弹出更新提示,并引导用户手动刷新页面(例如弹窗提示),完成应用更新。version.json 文件管理版本号使用
version.json文件管理版本内容,由开发者手动控制应用版本更新。 缺点是需要开发者手动维护version.json文件
Web WorkerAPI 在浏览器后台轮询请求version.json文件,不会影响主线程运行。version.json文件,对比当前文件和最新文件中的 version 字段值。适用于支持原生 ES Modules 的浏览器
chrome >= 87
edge >= 88
firefox >= 78
safari >= 14
# 本地项目安装
npm install version-polling --save
无侵入用法,接入成本最低
<script src="https://unpkg.com/version-polling/dist/version-polling.min.js"></script>
当检测到有新版本时,会触发onUpdate回调函数,弹出提示用户有更新,点击确定刷新页面。
// 在应用入口文件中使用: 如 main.js, app.jsx
import { createVersionPolling } from 'version-polling';
createVersionPolling({
silent: process.env.NODE_ENV === 'development', // 开发环境下不检测
onUpdate: (self) => {
const result = confirm('页面有更新,点击确定刷新页面!');
if (result) {
self.onRefresh();
} else {
self.onCancel();
}
},
});
import { createVersionPolling } from 'version-polling';
import { MessageBox } from 'element-ui';
createVersionPolling({
silent: process.env.NODE_ENV === 'development', // 开发环境下不检测
onUpdate: (self) => {
MessageBox.confirm('检测到网页有更新, 是否刷新页面加载最新版本?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
})
.then(() => {
self.onRefresh();
})
.catch(() => {
self.onCancel();
});
},
});
如果觉得前端轮询请求太频繁,可以设置轮询间隔为半小时。
import { createVersionPolling } from 'version-polling';
createVersionPolling({
pollingInterval: 30 * 60 * 1000, // 每 30 分钟检测一次
silent: process.env.NODE_ENV === 'development', // 开发环境下不检测
onUpdate: (self) => {
const result = confirm('页面有更新,点击确定刷新页面!');
if (result) {
self.onRefresh();
} else {
self.onCancel();
}
},
});
在浏览器页面导航跳转时、页面显示切换时,触发检测任务。
在Window上触发的事件。
import { createVersionPolling } from 'version-polling';
createVersionPolling({
eventTriggerList: ['popstate'],
silent: process.env.NODE_ENV === 'development', // 开发环境下不检测
silentPollingInterval: true,
onUpdate: (self) => {
const result = confirm('页面有更新,点击确定刷新页面!');
if (result) {
self.onRefresh();
} else {
self.onCancel();
}
},
});
由开发者自行决定触发检测的时机。
import { createVersionPolling } from 'version-polling';
createVersionPolling({
eventTriggerList: ['myEvent'],
silent: process.env.NODE_ENV === 'development', // 开发环境下不检测
onUpdate: (self) => {
const result = confirm('页面有更新,点击确定刷新页面!');
if (result) {
self.onRefresh();
} else {
self.onCancel();
}
},
});
通过dispatchEvent触发版本检测。
dispatchEvent(new CustomEvent('myEvent'));
还可以在路由跳转时触发,以Vue Router为例,借助导航守卫来触发版本检测。
router.afterEach((to, from) => {
dispatchEvent(new CustomEvent('myEvent'));
});
chunkHash使用chunkHash作为版本标识符,控制应用版本更新。以打包构建工具 vite 为例。
import { createVersionPolling } from 'version-polling';
createVersionPolling({
vcType: 'chunkHash',
chunkName: 'index',
silent: import.meta.env.MODE === 'development', // 开发环境下不检测
onUpdate: (self) => {
const result = confirm('页面有更新,点击确定刷新页面!');
if (result) {
self.onRefresh();
} else {
self.onCancel();
}
},
});
chunkName 也可能是其他值,例如 Vue CLI 是app,查看打包产物里index.html文件内容来确定。
versionJson使用version.json 文件管理版本号,控制应用版本更新。
import { createVersionPolling } from 'version-polling';
createVersionPolling({
vcType: 'versionJson',
silent: import.meta.env.MODE === 'development', // 开发环境下不检测
onUpdate: (self) => {
const result = confirm('页面有更新,点击确定刷新页面!');
if (result) {
self.onRefresh();
} else {
self.onCancel();
}
},
});
修改version.json文件,配置version字段值
{
"version": "2.1.0",
"versionContent": "更新内容: 修复已知存在的问题"
}
version.json文件跟index.html文件放在同一个服务器目录下。
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| vcType | 版本控制方式,可选值有etag、chunkHash、versionJson | string | etag |
| htmlFileUrl | index.html文件地址 | string | ${location.origin}${location.pathname} |
| chunkName | chunk 名称 | string | index |
| versionFileUrl | version.json文件地址 | string | ${location.origin}${location.pathname}version.json |
| eventTriggerList | 触发版本检测的事件名称列表 | string[] | - |
| pollingInterval | 轮询间隔,单位为毫秒,默认为 5 分钟 | number | 5 * 60 * 1000 |
| silent | 为true时,不进行版本检测 | boolean | false |
| silentPollingInterval | 为true时,不做轮询版本检测 | boolean | false |
| silentPageVisibility | 为true时,visibilitychange事件不会触发版本检测 | boolean | false |
| onUpdate | 检测到版本更新触发的回调函数 | (self) => void | - |
v1.3.0移除appETagKey、forceUpdate配置项,移除原因使用鸡肋FAQs
A JavaScript library for web application updates
The npm package version-polling receives a total of 129 weekly downloads. As such, version-polling popularity was classified as not popular.
We found that version-polling demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.