vue2,浏览器端自动检测更新-前端-E先生的博客
Java
MySQL
大数据
Python
前端
黑科技
大语言模型
    首页 >> 互联网 >> 前端

vue2,浏览器端自动检测更新

[导读]:vue2,浏览器端自动检测更新...

  大致思路是这样的,在autoRefresh,js中有个autoRefresh函数,每20s执行一次,它会每次请求根路径,去判断获取的html文件,而后通过正则去判断script标签中js文件名的变化,如果有变化,就会弹框提示用户去更新。

  这个逻辑应该不难理解,不过,我们还需要通过Nginx的配置来做适当的调整。

  比如:Nginx配置add_header Cache-Control"no-cache",此时浏览器不直接使用缓存,而是每次向服务器发送请求验证资源是否过期,如果没有过期使用缓存中的数据,如果过期了重新获取服务器中的数据。那么这里加时间戳就没有意义了。

  再比如:Nginx配置add_header Cache-Control"max-age=86400";缓存一天(可以设置长一点,我记得默认都很久的,js,css15天的,图片30天,html没有设置缓存时间),此时,在一天之内浏览器获取缓存中的数据,那么如果服务器中的数据发生了变化,此时加上时间戳就是有意义的了,因为不加时间戳,缓存没有过期的时候请求index.html文件的时候,还是取缓存中的数据,加上时间戳,浏览器会将其视为新的资源重新下载。

  由于我们Nginx配置的是add_header Cache-Control"no-cache",就不用加时间戳了。

  不过第二种做法,还有一丝丝的问题,我们来假设一下

  当用户打开了页面,而后关闭,过了比过期时间还要久的时候再打开页面,在此之前服务器的资源更新了,那么页面会获取最新的数据,在判断的时候lastScripts首先为空,而后20s再次获取是最新的html,此时比较就没问题。

  当用户打开了页面,而后关闭,此时服务器的资源更新,资源还没过期,用户打开页面,此时lastScripts也是存最新的html,这样就有问题了,因为此时应该提醒用户可以刷新一下页面。如何解决?

//autoUpdate.js
import { MessageBox } from 'element-ui';
let lastScripts = [];
/* 获取html中js资源名称 */
async function extractNewScripts (html) {
 const scriptReg = /<script.*src=["'](?<src>[^"']+)/gm;
 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(await fetch('/?_timestamp=' + Date.now()).then(resp => resp.text()));
 const newScripts = await extractNewScripts(await fetch('/').then(resp => resp.text()));
 if (!lastScripts.length) {
   lastScripts = newScripts;
   return false;
}
 let result = false;
 if (newScripts.length !== lastScripts.length) {
   result = true;
} else {
   for (let i = 0; i < lastScripts.length; i++) {
     if (lastScripts[i] !== newScripts[i]) {
       result = true;
       break;
    }
  }
}
 lastScripts = newScripts;
 return result;
}
/* 延时时间20s */
const DURATION = 20000;
/* 自动刷新 */
export const autoRefresh = () => {
 setTimeout(async () => {
   const willUpdate = await needUpdate();
   console.log(willUpdate);
   if (willUpdate) {
     MessageBox.confirm('页面有更新,点击确定刷新页面?', '提示', {
       confirmButtonText: '确定',
       cancelButtonText: '取消',
       type: 'warning'
    }).then(() => {
       // location.reload(true);来强制刷新页面并绕过缓存。如果不加true,浏览器可能会从其缓存中获取页面
       location.reload(true);
    }).catch(() => { });
  }
   autoRefresh();
}, DURATION);
}


//vue.config.js
module.exports = {
 configureWebpack: {
   output: {
     filename: `app-${new Date().getTime()}.js` // 修改文件名为你想要的名称  
  }
}
}


image.png


本文来自E先生的博客,如若转载,请注明出处:https://www.javajz.cn

留言区

联系人:
手   机:
内   容:
验证码:

历史留言

欢迎加Easy的QQ