vue自动清除缓存, 打包发版后,客户端页面自动更新

一:需求
页面打包上传到服务器后,用户能在自己电脑上立即感知到更新
二:需求分析
调研后得知:
1.靠浏览器缓存,各种catche啥的不靠谱. -----pass,缓存不会那么快生效
2.页面JS定时去查询服务器保存版本号的文件,查看版本号是否过期
---pass,效率太差,如果有十万用户,每个用户五分钟去服务器查询一次,服务器每
五分钟被查询五十万次.

三:实现方案
前端接口请求http-header 携带时间戳版本号,后端比对时间戳版本号.
如果请求带过来的时间戳小于服务器保存的,返回版本号过期错误.

如果请求带过来的时间戳大于服务器保存的时间戳,更新服务器时间戳版本号.
同时,如果请求没带版本号参数,则不对版本号进行校验,方便dev环境前端开发.
前端最好能自动生成版本号,自动更新,不用手动填值.

如果版本号过旧就执行JS代码location.reload(true),但是上线后有的人的浏览器
执行了location.reload(true) 或者ctrl+f5,有可能部分文件还是走的缓存.

所以弹窗让用户选择更新还是取消.如果选取消就清空版本号,后端不校验空的就行

四:具体代码应用
样例代码为vue2+webpack. 主要都是JS代码. vue3和react也可以参考

第一步修改 入口文件

在入口文件index.html创建一个同级别JS文件config.js
在index.html引入这个文件

 <script src="config.js?version=123456789"></script>
image.png

index.html引入文件后面有个后缀?version=123456789,为什么要带这个后缀呢?
因为不带部分浏览器会给你缓存了,哪怕用户ctrl+f5也不行,只能手动清理缓存.
这个后缀的数字123456789每次打包后都会被修改,为了方便就修改成版本号

第二步 创建config.js

代码如下,里面代码不重要,主要起到模板记录作用,因为每次打包会重新生成.
主要意思就是读取版本号变量timestamp 的值,并存入localStorage中,
这样接口请求的时候可以从localStorage读取timestamp 的值放到head带给后端.

 let timestamp = 1693386173000


        if(localStorage.timestamp){
          if(timestamp < localStorage.timestamp){
            console.log('timestamp is small')
          }else{
            console.log('timestamp is big')
            localStorage.timestamp = timestamp
          }
        }else{
          localStorage.timestamp = timestamp
        }
      
console.log('configjs read again')

上面代码除了注释可以删,每一行都有用,谨慎修改
3.修改vue.config.js
我们要在输入npm run build打包命令后,进行操作

引入node的文件函数,能读取文件

const fs = require("fs");
// 判断是否为生产环境
const isProd = process.env.NODE_ENV === "production";

然后在plugins下面放入同级函数

const Timestamp = new Date().getTime(); //时间戳
if (isProd) {

  fs.readFile("./public/config.js", "utf8", function(err, data) {
    if (err) {
      console.log(err)
      return
    }
    // console.log(data)
    try {
      //   data = data.replace('1693971026219',Timestamp)
      data = "";
      let c_1 = " let timestamp = " + Timestamp;
      console.log("c_1", c_1);
      data = c_1 + "\n" + data;

      let c_3 = "\n"+"console.log('configjs read again')"

      let c_4 = `
        if(localStorage.timestamp){
          if(timestamp < localStorage.timestamp){
            console.log('timestamp is small')
          }else{
            console.log('timestamp is big')
            localStorage.timestamp = timestamp
          }
        }else{
          localStorage.timestamp = timestamp
        }
      `
  
      data = data +"\n"+String(c_4)  + c_3
      console.log('result_data',data)
    } catch (err2) {
      console.log(err2);
    }
  
    fs.writeFile("./public/config.js", data, function(err) {
      if (err) {
        console.log(err)
      }
      console.log("configjs文件已修改");
    });
  });


  fs.readFile("./public/index.html", "utf8", function(err, data_2) {
    if (err) {
      console.log(err)
      return
    }
    // console.log(data)
    try {
         data_2 = data_2.replace('123456789',Timestamp)
     
    } catch (err2) {
      console.log(err2);
    }
  
    fs.writeFile("./public/index.html", data_2, function(err) {
      if (err) {
        console.log(err)
      }
      console.log("html文件已修改");
     // console.log("data_2",data_2)
    });
  });




}

该函数主要两个作用:
一是修改config.js文件,把里面的timestamp值换成最新的时间戳值
二是修改index.html文件,把config.js?version=123456789的后缀123456789换成时间戳,避免浏览器缓存

image.png

第三步 vue实例绑定弹窗

这步不是必须的,因为要在axios的配置文件拦截响应,如果报版本号过期,要弹窗提示用户是否更新页面.
博主用的UI组件是antdvue 1.X,如果想在JS文件用vue的弹窗插件,需要先把这个弹窗插件绑定在vue实例上.

所以在app.vue执行如下操作,给vue实例加个弹窗绑定.
弹窗记得要JS防抖.

mounted(){
   // console.log('app vue')
   // console.log(this.$confirm)
    Vue.$confirm = this.$confirm
  }

第四步 校验版本号

和后端约定,如果版本号旧了,在返回的data对象里code属性报402.
在axios的配置文件,相应拦截回调函数里配置402错误对应的执行代码.
记得按照你和后端的约定修改代码

  response => {
    if (
      response.data.code != 200 &&
      response.request.responseType != "arraybuffer" &&
      response.data.info !== "成功"
    ) {

  

      //版本旧了
      if (response.data.code == 402) {
        console.log('行为分析 接口报402 错误码')

        
      //    location.reload(true) 

          if (timer_request) {
            clearTimeout(timer_request)
          }
          timer_request = setTimeout(() => {
            console.log(88945)
            // localStorage.timestamp = ''
            // location.reload(true) 


            Vue.$confirm({
              title: '检测到新版本,是否立即更新页面?',
              content: h =>(
              <div style="">
                点击取消,后续将不再检测版本,
                除非手动更新页面或者等待浏览器自动更新缓存后才继续检测
              </div>
              ) ,
              onOk() {
                console.log('OK');
                 localStorage.timestamp = ''
                 location.reload(true)
              },
              onCancel() {
                console.log('Cancel');
                localStorage.timestamp = ''
              },
            });




          }, 4000)
        
        
       
        
      }

      return response;
    }

    return response;
  },
image.png

第五步 打包上线

1.如果你是自动部署,比如把代码提交到git,jekines自动部署,代码直接提上去就行
2.如果你是本机打包好后,手动把打包文件传到服务器部署.
那么每次执行打包操作,你的index.html和config.js都会被修改,生成打包文件后记得还原下

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352

推荐阅读更多精彩内容