前端项目部署后,自动刷新用户页面

118 阅读1分钟

 通过轮询的方式,查询script地址。通过比较每次查询到的结果,如果不一样则刷新页面

完整代码

/**生产环境纯前端通过轮询来自动更新页面*/
let lastSrcs // 上一次获取到的script地址
let setTimeoutId
let DURATION = 5000

/**正则校验html中的src */
const scriptReg = /<script.*src=["'](?<src>[^"']+)/gm

/**获取最新的html中的内容并将src=""中的数据拿出来*/
async function fetchScriptUrl() {
    try {
        const resp = await fetch('/?_timestamp=' + Date.now())
        const text = await resp.text()
        return text
    } catch (error) {
        return undefined
    }
}
/**对获取到的html中的src的内容进行操作 */
async function extractNewScripts() {
    const html = await fetchScriptUrl()
    scriptReg.lastIndex = 0
    let result = []
    let match
    while ((match = scriptReg.exec(html))) {
        result.push(match.groups.src)
    }
    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 (let i = 0; i < lastSrcs.length; i++) {
        if (lastSrcs[i] !== newScripts[i]) {
            result = true
            break
        }
    }
    lastSrcs = newScripts
    return result
}
/**执行自动检测,如果为true则刷新页面,也可以进行弹框提醒,可自行添加*/
async function autoUpdate() {
    setTimeoutId = setTimeout(async () => {
        const willUpdate = await needUpdate()
        console.log(willUpdate)
        if (willUpdate) {
            location.reload()
        }
        autoUpdate()
    }, DURATION)
}

function autoStop() {
    console.log('停止刷新')
    if (setTimeoutId) {
        clearTimeout(setTimeoutId)
        setTimeoutId = ''
    }
}

/**如果页面隐藏或离开,将不执行刷新,当回到当前页面再执行刷新 */
function autoRefresh() {
    document.addEventListener('visibilitychange', () => {
        let hidden = document.hidden
        if (!hidden) {
            autoUpdate()
        } else {
            autoStop()
        }
    })
}

autoUpdate()

main.ts直接引用即可

import './auto-update'