背景:
当我们重新部署前端项目时,用户一直停留在页面,未刷新使用,会存在功能使用差异问题,若后端接口不检验,兼容,会产生脏数据。 每次上线都要人工传播。
因此当前端部署项目后,需要提醒用户有去重新加载页面。
需求:
版本更新后,系统自动出现刷新提醒。
立即刷新:刷新浏览器。 不再提醒,直到下次发版再提醒。
稍后刷新:一小时后再次出现提示弹窗。
前提:确保浏览器不缓存,刷新可获取最新版本。
- 在 .html 页面加 meta 标签, 确保浏览器每次都能获取到页面的最新版本。
// 浏览器不要使用缓存。
<meta http-equiv="pragma" content="no-cache">
// 不适用缓存、不存储、页面过期重新请求
<meta http-equiv="cache-control" content="no-cache, no-store, must-revalidate">
// 立即过期
<meta http-equiv="expires" content="0">
- 脚手架配置, 打包后 css 和 js 的名字后面都哈希值或者时间戳。
output: {
//静态资源分类打包
chunkFileNames: 'static/js/[name]-[hash].js',
entryFileNames: 'static/js/[name]-[hash].js',
assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
}
3. 后端 nginx 配置,让 index.html 不缓存。
location = /index.html { add_header Cache-Control "no-cache, no-store"; }
有新版本发布,弹窗提醒。
原理: 对比本地html的版本和远程的版本号是否一致。
创建auto-update.js, 定时刷新,提醒弹窗。
- 定时任务每隔1小时,检查是否有新版本。 对比本地version和远程version
import { MessageBox } from 'element-ui'
localStorage.setItem('needTip', 'true'); // 是否开启刷新提示
function checkVersion () {
return new Promise(resolve => {
fetch(`${window.location.origin}/admin/version.json?v=${new Date().getTime()}`, {
headers: {
'Cache-Control': 'no-cache'
}
}).then(async res => {
try {
const text = await res.text();
const data = JSON.parse(text);
resolve(data.version === Number(document.querySelector('#appVersion').content));
} catch (error) {
console.error('Error fetching or parsing version.json:', error);
resolve(false); // Resolve with false indicating version check failed
}
}).catch(error => {
console.error('Fetch error:', error);
resolve(false); // Resolve with false indicating version check failed
});
});
}
// 是否弹出提示窗,防止重复弹出
let isShow = false
function autoRefresh () {
if (localStorage.getItem('needTip') == 'true') {
setTimeout(async () => {
if (!isShow) { // 防止重复弹出
const flag = await checkVersion();
if (!flag) {
isShow = true
MessageBox.confirm('检测到当前版本不是最新版本,刷新浏览器后即可正常使用。', '提示', {
confirmButtonText: '立即刷新',
cancelButtonText: '稍后刷新',
type: 'warning',
}).then(() => {
window.location.reload();
}).catch(() => {
isShow = false // 重置是否弹出提示窗
});
}
}
autoRefresh();
}, 3600000)
}
}
// 一小时执行一次
autoRefresh();
main.js 中引入。
// 引入自动更新提醒
import "@/utils/auto-update.js"
创建version数据,并打包传到远程。
// version.js
const fs = require('fs');
const timestamp = new Date().getTime();
fs.writeFile('./public/version.json', `{"version": ${timestamp}}`, err => {
if (err) {
console.error(err);
}
});
打包命令配置: 执行打包命令,创建version。
"build:rel": "node version.js && vue-cli-service build --mode release",
html添加version。
html 添加标签
<meta id="appVersion" name="version" content="<%= htmlWebpackPlugin.options.version%>" />
vite.config.js文件中配置
const AppVersion = require('./public/version.json')
// 可以在 index.html 文件内访问到版本号(AppVersion.version)
config.plugin('html').tap(args => {
args[0].version = AppVersion.version;
return args;
});