vue 版本更新,导致页面白屏的解决方法

vue 版本更新,用户未刷新导致页面白屏的解决方法

方法一:本地轮询查询 index.html 的 js 文件携带的 hash/时间戳 数据

export class Updater {
  timerId = null //轮询定时器id
  constructor(options) {
    this.oldScript = []
    this.newScript = []
    this.dispatch = {}
    this.init() //初始化
    this.timing(options?.timer) //轮询
  }

  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+[^>]*)?>(.*?)<\/script\s*>/gi) //script正则
    return html.match(reg) //匹配script标签
  }

  /**
   * @name: 发布订阅通知
   * @param {*} key : 'no-update' | 'update'
   * @param {*} fn
   */
  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()
      })
    }
  }

  timing(time = 10000) {
    if (process.env.NODE_ENV === 'development') return //开发环境不轮询
    //轮询
    this.timerId = setInterval(async () => {
      const newHtml = await this.getHtml()
      this.newScript = this.parserScript(newHtml)
      this.compare(this.oldScript, this.newScript)
    }, time)
  }

  // 开启轮询
  start() {
    this.timing()
  }

  // 停止轮询
  stop() {
    this.timerId && clearInterval(this.timerId)
  }
}

//实例化该类
export const up = new Updater({
  timer: 5000,
})

/**
 * @name: 未更新通知
 * @param {*} callBack
 */
export function noUpdateFun(callBack) {
  //未更新通知
  up.on('no-update', () => {
    typeof callBack === 'function' && callBack.call(this)
  })
}

/**
 * @name: 更新通知
 * @param {*} callBack
 */
export function updateFun(callBack) {
  //更新通知
  up.on('update', () => {
    typeof callBack === 'function' && callBack.call(this)
  })
}

// 使用方法
// 非开发环境下版本更新检测
// if (process.env.NODE_ENV !== 'development') {
//   updateFun(() => {
//     this.$confirm('应用已更新,请刷新页面!', '提示', {
//       confirmButtonText: '确定',
//       showClose: false,
//       showCancelButton: false,
//       closeOnClickModal: false,
//       closeOnPressEscape: false,
//       type: 'warning',
//     }).then(() => {
//       window.location.reload(true)
//     })
//     // 停止轮询,等待用户操作
//     up.stop()
//   })
// }

方法2:nginx 配置 index.html 不缓存

  • 注意只配置 index.html 不缓存,如果都不缓存,每次刷新都全部重新请求,不如使用方法一的轮询,消耗还小一些
配置nginx的html不缓存并重启nginx
vim nginx.cong
将以下内容写入并 :wq 保存
        location / {
            root   web/;
            index  index.html;
            try_files $uri $uri/ /index.html;
            # add_header Cache-Control "no-cache, no-store";
            # 控制版本更新缓存 - 不推荐,导致所有文件不被缓存
            # add_header Cache-Control "no-cache, no-store, must-revalidate";
            # add_header Pragma "no-cache";
            # add_header Expires 0;
            #以下配置解决html不缓存,也可以配置cssjs分别缓存7天和30天。这里未配置
            if ($request_filename ~* .*\.(?:htm|html)$)
            {
                add_header Cache-Control "private, no-store, no-cache";
            }
        }
  • 重启nginx
    • 进入 /usr/local/nginx/sbin 路径,会存在一个 nginx 的文件
./nginx -s reload
如果以上未生效,可能是进程导致,需要停用再启动
  • 查询所有nginx的进程
    1. 会获取一个进程的 pid
ps aux | grep nginx

效果如图

  • 根据 pid 查询进程监听 端口号,找到控制 80端口的pid
netstat -anp | grep {pid}

80端口被该pid监听

  • 杀死进程
kill {pid}
或者
kill -9 {pid}
  • 重新启动进程,执行nginx即可
    • 进入 /usr/local/nginx/sbin 路径,会存在一个 nginx 的文件
./nginx
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值