前端部署发布项目后,如何通知用户刷新页面、清除缓存

以下只是一些思路,有更好的实现方式可以留言一起交流学习

方式一:纯前端
在每次发布前端时,使用webpack构建命令生成一个json文件,json中写个随机生成的一个字符串(比如时间戳),每次打包程序都会自动更新这个json文件。
在项目中,通过定时任务或者在切换页面路由时,请求json文件。使用本地保存的上一次生成的字符串和json文件中的字符串进行比较,如果两个字符串不一样,则说明前端重新部署了,提醒用户进行更新或进行强制刷新的操作。

方式二:前后端配合
在每个请求的header里面加上发版版本号,和保留在客户端的上一次版本号进行比较,如果不一致则强制刷新,刷新后保存当前版本号。(或者单独写一个返回版本号的接口)

下面重点说一下纯前端如何做:

①webpack 4构建 生成一个json文件,在项目目录下新建plugin文件夹,新建version-webpack-plugin.js如下

/** 自定义的插件: 生成版本号json文件 */
const fs = require("fs");
class VersionPlugin {
  apply(compiler) {
    // emit 是异步 hook,使用 tapAsync 触及它,还可以使用 tapPromise/tap(同步)
    compiler.hooks.emit.tap("Version Plugin", (compilation) => {
      const outputPath = compiler.path || compilation.options.output.path;
      const versionFile = outputPath + "/version.json";
      const timestamp = Date.now(); // 时间戳作为版本号
      const content = `{"version": "${timestamp}"}`;
 
      /** 如果路径存在则返回 true,否则返回 false。 */
      if (!fs.existsSync(outputPath)) {
        // 同步地创建目录。 返回 undefined 或创建的第一个目录路径(如果 recursive 为 true)。 这是 fs.mkdir() 的同步版本。
        fs.mkdirSync(outputPath, { recursive: true }); 
      }
      // 生成json文件
      fs.writeFileSync(versionFile, content, {
        encoding: "utf8",
        flag: "w",
      });
    });
  }
}
 
module.exports = { VersionPlugin };

webpack3低版本的构建方式

/** 自定义的插件: 生成版本号json文件 */
const fs = require('fs')
class VersionPlugin {
  apply (compiler) {
    compiler.plugin('done', function () {
      // 复制文件的逻辑,此时文件已经编译完成
      const outputPath = compiler.outputPath
      const versionFile = outputPath + '/version.json'
      const timestamp = Date.now() // 时间戳作为版本号
      const content = `{"version": "${timestamp}"}`

      /** 如果路径存在则返回 true,否则返回 false。 */
      if (!fs.existsSync(outputPath)) {
        // 同步地创建目录。 返回 undefined 或创建的第一个目录路径(如果 recursive 为 true)。 这是 fs.mkdir() 的同步版本。
        fs.mkdirSync(outputPath, { recursive: true })
      }
      // 生成json文件
      fs.writeFileSync(versionFile, content, {
        encoding: 'utf8',
        flag: 'w'
      })
    })
  }
}

module.exports = { VersionPlugin }

②在vue.config.js中使用这个 plugin

const { VersionPlugin } = require('./plugin/version-webpack-plugin.js');

③在每次执行webpack构建命令,都会在dist目录下生成一个version.json文件,里面有一个字段叫 version,值是构建时的时间戳,每次构建都会生成一个新的时间戳。

④发起ajax请求,请求version.json文件获取version时间戳,和本地保存的上一次的时间戳做比较,如果不一样,则进行对应的操作。/plm/version.json,plm是我项目的前缀,改成你自己的项目地址,能请求到 version.json文件就行。

import axios from 'axios'
import {MessageBox} from 'element-ui'
export function reloadVersion() {
    axios.get(window.location.origin + '/plm/version.json?v=' + Date.now()).then(rsp => {
        let localVersion = localStorage.getItem('localVersion')
        let onlineVersion = rsp.data.version
        if(onlineVersion){
            if(localVersion!==onlineVersion){
                // 弹框提示更新
                MessageBox.confirm('有版本更新,是否刷新确保获取最新数据?', '版本更新', {
                    confirmButtonText: '更新',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    // 发版版本号和本地版本号不一致,保存最新的版本号到本地,并刷新页面获取最新的页面
                    localStorage.setItem('localVersion',onlineVersion)
                    window.location.reload();
                })
            }
        }
    })
}
  

⑤请求发起的时机,可以使用定时器或者在切换页面的时候进行校验版本。根据自己的实际情况选择合适的调用时机。 

(二)通过监听网页端的报错,进行相应的处理。

如果是覆盖式的更新,有可能发版前就已经删除了上一个版本的dist文件,会造成缓存的页面依然调用已经被删除的文件,所以会白屏报错。报错就有可能不会执行到上面发起请求获取版本号的操作。所以如果监听到如下的几种报错,可以进行刷新页面的操作,

在index.html根目录文件中加入如下代码。为了防止页面一直刷新,所以加了一个超过次数就不再继续刷新的逻辑

  <script>
    // 错误监听
    window.addEventListener('error', (e) => {
      console.log('globalError'+e)
      // 类似manifest.js和app.js等静态资源报错
      if(e.target.outerHTML.indexOf('js/manifest.') != -1 || e.target.outerHTML.indexOf('js/app.') != -1|| e.target.outerHTML.indexOf('js/chunk-') != -1){
        var errorTime = sessionStorage.getItem('mainAppErrorTime')
        if(errorTime&&errorTime>0){
          errorTime++
        } else{
          errorTime = 1
        }
        var timer = setTimeout(function() {
          // 错误次数存在缓存,刷新超过3次不会继续刷新。退出页面重进后,次数重置
          sessionStorage.setItem('mainAppErrorTime', errorTime)
          window.location.reload()
        }, 1000);
        if(errorTime&&errorTime>=3){
          clearTimeout(timer) // 清空定时器
        }
      }
    }, true);
  </script>

  • 6
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在web项目中,页面缓存清除是指从浏览器缓存中删除已缓存的页面数据,以便在下次访问相同页面时重新获取最新版本的页面内容。这样可以保证用户能够看到最新的页面展示,而不是过时的缓存数据。 传统的做法是通过手动刷新浏览器来清除页面缓存,但这种方法需要用户主动操作,不够便捷。为了解决这个问题,我们可以借助一些技术手段,实现自动清除页面缓存,而不需要每次刷新浏览器。 一种常见的方法是在网页的URL中加入一个时间戳或版本号参数。当页面内容发生改变时,例如更新了CSS样式或JS脚本,我们可以通过修改URL中的时间戳或版本号,使浏览器认为该页面是一个新的资源,从而强制重新加载页面内容。 另一种方法是使用HTTP响应头中的Cache-Control和Expires字段。通过设置这些字段的值为0或一个未来的日期,我们可以指示浏览器在访问该页面时不要使用缓存,而总是重新从服务器获取最新的页面内容。 除了以上两种方法,我们还可以使用一些前端开发框架或工具,如React、Angular或Vue.js等,在开发过程中自动处理页面的缓存清除。这些框架通常具有自动或手动的缓存清除机制,可以根据开发者的需求灵活配置。 总结来说,为了实现页面缓存清除,不需要每次刷新浏览器,我们可以通过在URL中添加时间戳或版本号参数、为HTTP响应头定义适当的缓存控制字段、或使用前端开发框架来自动处理缓存清除。这些方法都可以确保用户在访问web项目时能够得到最新的页面内容,提供更好的用户体验。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值