Vue纯前端实现重新部署后通知用户刷新网页

1.目标场景

前端打包上线,用户还停留在旧的页面,用户不知道网页重新部署了,发送请求报500或者页面显示不出数据,并且用户体验不到新功能。

2.解决方案(1)

如果后端可以配合话可以用webSocket 跟后端进行实时通讯,前端部署完之后,后端给个通知,前端检测到Message进行提示,还可以在优化一下使用EvnentSource 这个跟socket很像只不过他只能后端往前端推送消息,前端无法给后端发送,我们也不需要给后端发送。

 以上方案需要后端配合,奈何后端都很忙,需要纯前端实现。

2.解决方案(2)

根据打完包之后生成的script src 的hash值去判断,每次打包都会生成唯一的hash值,只要轮询去判断不一样了,那一定是重新部署了。

3.代码实现

        当前使用版本为Vue2.5.2;

        需要实现一个简单的发布订阅模式;

        在until目录下新建一个AutoUpdate.js文件;

        文件路径:src-->until-->AutoUpdate.js

        下面是AutoUpdate.js文件


/**
 * 前端重新部署通知用户刷新网页
 */

class Updater {
    oldScript = []; // 存储第一次值也就是script 的hash 信息
    newScript = []; // 获取新的值 也就是新的script 的hash信息
    dispatch = {}; // 小型发布订阅通知用户更新了

    constructor() {
        this.oldScript = [];
        this.newScript = [];
        this.dispatch = {};
        this.init(); // 初始化
        this.timing();
    }

    async init() {
        const html = await this.getHtml();
        this.oldScript = this.parserScript(html);
    };

    async getHtml() {
        const html = await fetch('/').then(res => res.text());//读取index html
        return html
    };

    parserScript(html) {
        const reg = new RegExp(/]*)?>(.*?)<\/script\s*>/ig) //script正则
        return html.match(reg) //匹配script标签
    }

    //发布订阅通知
    on(key, fn) {
        (this.dispatch[key] || (this.dispatch[key] = [])).push(fn)
        return this;
    }

    compare(oldArr, newArr) {
        const base = oldArr.length;
        const arr = Array.from(new Set(oldArr.concat(newArr)));
        //如果新旧length 一样无更新
        if (arr.length === base) {
            // this.dispatch['no-update'].forEach(fn => {
            //     fn();
            // })
        } else {
            // 否则通知更新
            this.dispatch['update'].forEach(fn => {
                fn();
            })
        }
    };

    async timing() {
        setInterval(async () => {
            const newHtml = await this.getHtml();
            this.newScript = this.parserScript(newHtml);
            this.compare(this.oldScript, this.newScript)
            //这边给的是默认值15000,也可以自定义秒数
        }, 15000);
    };
}

export default Updater;

         然后在main.js文件中引入并使用即可

         文件路径:src-->main.js

import Vue from 'vue'

import Updater from "./utils/NewAutoUpdate";

//前端重新部署通知用户刷新网页
const AutoUpdate = new Updater()
AutoUpdate.on('update',()=>{
  setTimeout(async()=>{
      const result = confirm('当前网站有更新,请点击确定刷新页面体验');
      if(result){
        location.reload();
      }
  },500)
})


new Vue({
  el: '#app',
  render: h => h(App)
});

你可能感兴趣的:(javascript,Vue,vue.js,javascript,正则表达式,es6,前端框架)