北屋教程网

专注编程知识分享,从入门到精通的编程学习平台

前端如何检测新版本,并提示用户去刷新

前端如何检测新版本,并提示用户去刷新

先看效果

原理

通过轮询index.html文件的内容来计算文件的哈希值前后是否发生了变化

前端工程化的项目中,以Vue为例,webpack或vite打包通常会构建为很多的js、css文件,每次构建都会根据内容生成唯一的哈希值

大家可以动手试试,观察一下。

每次构建完index.html中script或link标签引用的地址发生了变化。

代码实现

以Vue+ElementPlus项目为例。在入口文件中引入此文件即可。

// check-version.ts
// 封装了storage,粗暴一点可以用 sessionStorage 代替
import { Storage } from "@/utils/storage";
import { ElLink, ElNotification, ElSpace } from "element-plus";
import { h } from "vue";
import CryptoJS from 'crypto-js';
const storage = new Storage('check-version', sessionStorage);
const APP_VERSION = 'app-version';
let notifyInstance: any;
const generateHash = (text: string): string => CryptoJS.SHA256(text).toString();
const getAppVersionHash = async () => {
const html = await fetch(`${location.origin}?t=${Date.now()}`).then(res => res.text());
const newHash = generateHash(html);
const oldHash = storage.get(APP_VERSION);
return { newHash, oldHash };
}
const checkVersion = async () => {
const { newHash, oldHash } = await getAppVersionHash()
if (oldHash !== newHash) {
if (notifyInstance) return;
notifyInstance = ElNotification({
title: '版本更新',
message: h(ElSpace, null, () => [
h('span', '检测到新版本发布!'),
h(ElLink, { type: 'primary', onClick: () => location.reload() }, () => '立即刷新')
]),
position: 'top-right',
duration: 0,
onClose: () => {
notifyInstance = null
}
})
}
}
const loopCheck = (ms: number) => {
setTimeout(async () => {
await checkVersion()
loopCheck(ms)
}, ms)
}
document.addEventListener('DOMContentLoaded', async () => {
console.log("The DOM is fully loaded and parsed.");
const { newHash } = await getAppVersionHash();
storage.set(APP_VERSION, newHash, null);
loopCheck(1000 * 30);
});
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言