前端项目中如何实现版本自动检测和更新提醒
在前端项目比如管理后台、H5、官网中等,用户可能会遇到一些问题,项目功能更新了,但是用户也没有刷新页面,导致项目无法正常使用。这个时候,我们就需要实现一个自动检测和更新提醒的功能,提醒用户及时刷新页面,避免无法正常使用新功能。
方式一. 前端和后端配合实现自动检测和更新提醒
- 后端实现一个接口,返回最新的版本号、更新内容等信息。
 - 前端轮训请求该接口,获取到最新版本号后,判断是否需要更新。
 - 如果需要更新,则弹窗提示用户刷新页面。
 
方式二. 前端自己查询配置文件或获取项目文件的hash值来判断
- 通过请求配置文件来判断 + 在项目中定义一个version.json文件。 + 在打包时,将版本号写入该文件。 + 运行时,读取本地存储的版本号,将本地存储的版本号与当前版本号进行对比,如果版本号不一致,则提示用户更新。
 
例如:
import axios from 'axios';
axios.get('xxx/version.json')
  .then(res => {
    const serverVersion = res.data.version;
    const localVersion = localStorage.getItem('version');
    if (serverVersion !== localVersion) {
      // 提示用户更新
      alert('有新版本,请刷新页面');
      localStorage.setItem('version', serverVersion);
    }
  })
  .catch(err => {
    console.error(err);
  });
      
- 通过获取项目文件的hash值来判断 + 打包时配置打包代码,为打包的文件自动添加hash值 + 新建version-upgrade.js,用于检测项目文件是否更新,并提醒用户刷新
 
示例代码如下:
vue.config.js
const path = require("path");
function getAssetPath(assetsDir, filePath) {
  return assetsDir ? path.posix.join(assetsDir, filePath) : filePath;
}
chainWebpack: config => {
  const filename = getAssetPath("static", `/js/[name]-[hash].js`);
  config.output.filename(filename).chunkFilename(filename);
},
  
version-upgrade.js
const DURATION = 60 * 1000; // 版本更新检测间隔时间
// 获取app.js 的哈希值
const getAppHash = scripts => {
  let localVersion = "";
  for (let i = 0; i < scripts.length; i++) {
    const src = scripts[i].getAttribute("src");
    if (src && src.indexOf("app-") != -1) {
      // 正则返回中间版本号(如果没有,返回空)
      const regRes = /app-(.*?).js/;
      if (regRes.test(src)) {
        localVersion = regRes.exec(src)[1];
      }
    }
  }
  return localVersion;
};
// 获取本地的app.js版本号
const getLocalHash = () => {
  return getAppHash(document.getElementsByTagName("script"));
};
// 获取线上的app.js版本号
const getLastestHash = () => {
  return new Promise((resolve, reject) => {
    const href = window.location.href;
    // 加上时间戳,防止缓存
    fetch(href + "?time=" + Date.now())
      .then(async res => {
        const html = await res.text(); // 转成字符串判断
        const doc = new DOMParser().parseFromString(html, "text/html");
        const newVersion = getAppHash(doc.getElementsByTagName("script"));
        resolve(newVersion);
      })
      .catch(err => {
        console.log("获取版本号失败", err);
        reject(err);
      });
  });
};
// 定时执行,自动更新逻辑(每10s检测一次)
export const autoRefresh = () => {
  setInterval(async () => {
    // 本地
    const localVersion = getLocalHash();
    // 线上
    const newVersion = await getLastestHash();
    // 如果不一样,就进行刷新
    if (localVersion !== newVersion) {
      console.log("有新版本,自动刷新页面");
      window.location.reload(true);
    }
  }, DURATION);
};
- 在App.vue中引入并执行autoRefresh方法.
 
import { autoRefresh } from "@/utils/version-upgrade";
export default {
  mounted() {
    const is_localhost = window.location.hostname === "localhost";
    !is_localhost && autoRefresh();
  }
};
