Skip to content

页面自动检测更新

作者:Yuan Tang
更新于:5 个月前
字数统计:453 字
阅读时长:1 分钟

每隔一段时间去监测是否是最新的版本。实现步骤为:

  1. 使用 fetch 请求首页为纯文本,获取 html 中的 js 文件
  2. 前端工程化下,对应的 js 文件会绑定文件指纹,只要有变动,文件指纹(也就是 hash 值)也会发生变动,表示当前有新版本

文件指纹代码如下所示:

js
fetch('/').then(resp => resp.text()).then(res => console.log(res))

具体效果以 B站 为例,效果如下:

xiaoguo

因此可以封装一下相应的方法函数,首先获取最新页面中的 script 链接,代码如下:

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

const scriptReg = /\<script.*src=<CustomLink title=""'" href="?<src>[^"']+" />/gm

async function extractNewScripts() {
  // 避免缓存
  const html = await fetch(`/?_timestamp=${Date.now()}`).then(resp => resp.text())

  // 通过正则把首页js地址保存出来
  scriptReg.lastIndex = 0
  const result = []
  let match
  // 把所有对应js文件名称保存到数组内,最后返回
  while ((match = scriptReg.exec(html)))
    result.push(match.groups.src)

  return result
}

然后调用上方函数,拿到所有 JS 访问地址,并且保存到全局变量内。然后比较旧的地址与新的地址是否一致,不一致则返回 true 表示需要更新。代码如下:

js
async function needUpdate() {
  const newScripts = await extractNewScripts()
  // 如果没有值则是第一次,不需要更新,直接保存值
  if (!lastSrcs) {
    lastSrcs = newScripts
    return false
  }
  let result = false
  // 如果需要更新,result改为true
  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
}

调用上方的方法查看是否需要更新,如果需要则显示对应的提示。每隔一段时间调用一次,代码如下:

js
const DURATION = 2000
function autoRefresh() {
  setTimeout(async () => {
    const willUpdate = await needUpdate()
    if (willUpdate) {
      const result = confirm('页面需要更新')
      if (result)
        location.reload()
    }
    autoRefresh()
  }, DURATION)
}

autoRefresh()

Contributors

Yuan Tang