前端升级客户端自动更新

发布时间 2023-11-20 17:04:24作者: bbigger004

SPA类型应用,前端热发布后,用户端由于浏览器缓存不会重新获取index.html 导致用户没有及时看到最新版本
所以写了一个插件用户协助客户端实时更新

//思路:对比每一个script中的src的地址有无变化   因为打包后的js名称一般为   test.dawe13s5.js  中间8位为哈希值 每次打包均不一样·

//将此文件导入main.js 即可


let lastSrcs //上一次的所有script地址
const scriptReg = new RegExp('<script\\b[^<]*\\bsrc\\s*=\\s*["\']([^"\']*)["\'][^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>', 'gi');


async function extractNewScripts() {

  const html = await fetch('/?_timestamp='  +Date.now()).then(res => {
    res.text()
  })
  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) {  //script个数不一样 肯定有更新
    result = true
  }
  for (let 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()  // == F5
       location.href = location.href + '?timestamp=' + new Date().now();  //删除缓存重新加载 == Ctrl + F5

      }
    }
    autoRefresh()
  },DURATION)
}


autoRefresh()