自动检查更新

在我们单页面应用(Vue/React等)中,经常出现项目重新打包发布服务器,而此时用户正在访问页面,打包发布后由于用户本地缓存缓存了站点静态资源数据,所有用户还可以正常使用。如何检测并通知正在使用站点的用户站点已经重新发布了。

原理:

项目每次打包后都会在根目录生成一个index.html的文件,项目打包过程中构建工具会动态的在index.html文件中引入带有唯一指纹值的***[指纹].js,项目中可以循环调用/这个接口拿到index.html中的值,调用的结果进行对比。

实现代码:

let lastSrcs; // 上一次获取到的的script地址

const scriptReg = /<script.*src=["'](?<src>[^"']+)/gm;

async function extractNewScripts() {
    const html = await fetch('/?_timestamp=' + new Date()).then((res)=>res.text());
    scriptReg.lastIndex = 0;
    let result = [];
    let match;
    while ((match = scriptReg.exec(html))){
        result.push(match.groups.src);
    }
    console.log(result);
    return result;
}

async function needUpdate(){
    const newScripts = await extractNewScripts();
    if(!lastSrcs){
        lastSrcs = newScripts;
        return false;
    }
    let result = false;
    if (lastSrcs.length !== newScripts.length){
        result = true
    }
    for (var i = 0; i < lastSrcs.length; i++) {
        if(lastSrcs[i] !== newScripts[i]) {
            result = true;
            break;
        }
    }
    lastSrcs = newScripts;
    return result;
}

const DURATION = 2000;
function autoRefresh(){
    setTimeout( async ()=>{
        const willUpdate = await needUpdate();
        if(willUpdate){
            const result = confirm('页面有更新,点击确定刷新页面');
            if(result){
                location.reload();
            }
        }
        autoRefresh()
    }, DURATION);
}

autoRefresh()