利用TTP协议 ETag + 路由守卫 实现前端发版后通知用户更新得一个方案

​

利用 ETag 做提示更新的实现方案

ETag(Entity Tag)是万维网协议HTTP的一部分,是HTTP协议提供的若干机制中的一种Web缓存验证机制,是一个可以与Web资源关联的记号(token),并且允许客户端进行缓存协商,这使得缓存变得更加高效,而且节省带宽:

演示网站:http://www.xpclm.online/pdf-h5

原理:

1.首次请求资源:客户端通过HTTP GET请求向服务器请求/pdf-h5/资源。服务器处理请求后,生成资源的ETag,并在响应头中包含ETag返回给客户端。

2.​资源缓存:客户端接收到资源后将其存储在本地缓存中,并记录下ETag("68031a34-2a5")值。

如图所示👇

​编辑

3.后续请求资源:当客户端再次请求同一个资源时,会在请求头中包含之前缓存的ETag值。

4.服务器处理:服务器收到带有ETag的请求后,会比对服务器上当前资源的ETag和请求头中的ETag。如果ETag相同,表示资源没有改变,服务器就会返回304 Not Modified状态码,告诉客户端使用缓存中的资源即可。如果ETag不同,也表示资源已经更新,服务器就会返回200 OK状态码,并在响应体中包含新的资源内容和新的ETag

HTTP状态码304表示"Not Modified",即资源未修改。

再次访问刷新访问界面👇

​编辑

利用 ETag 做提示更新的实现思路👇

​第一步:首次加载页面 将这个 ETag 值存储起来,比如存储在 localStorage 中。

​第二步:定义路由守卫 这里我们选用全局前置守卫 beforeEach,因为它会在每次路由跳转前执行,客户端再次向服务器发送请求,获取 HTML 文件的响应头信息,从中提取新的 ETag 值。

​第三步:​对比 ETag 值 将新获取的 ETag 值与之前存储的 ETag 值进行比较。

示例代码:

javascript 复制代码
import Vue from 'vue';
import VueRouter from 'vue-router';
import routes from './routes';

Vue.use(VueRouter);

const router = new VueRouter({
  mode: 'history',
  routes
});

// 定义检查更新的函数
function checkForUpdates() {
  return new Promise((resolve, reject) => {
    // 使用 fetch API 发送一个 HEAD 请求到 /index.html
    fetch('/index.html', {
      method: 'HEAD'
    })
   .then(response => {
        // 从响应头中获取 ETag 值
        const newEtag = response.headers.get('ETag');
        // 从 localStorage 中获取当前存储的 ETag 值
        const currentEtag = localStorage.getItem('etag');
        // 如果当前 ETag 存在且与新 ETag 不同,表示资源已更新
        if (currentEtag && currentEtag!== newEtag) {
          // 提示用户有新版本可用,建议刷新页面
          alert('新版本可用,请刷新页面以更新。');
          // 将新的 ETag 值存储到 localStorage 中
          localStorage.setItem('etag', newEtag);
        }
        resolve();
      })
   .catch(error => {
        // 如果请求失败,输出错误信息到控制台
        console.error('版本检查失败:', error);
        resolve();
      });
  });
}

// 注册全局前置守卫
router.beforeEach(async (to, from, next) => {
  try {
    // 在路由跳转前检查更新
    await checkForUpdates();
    // 检查通过,继续路由跳转
    next();
  } catch (error) {
    // 检查出错,继续路由跳转
    next();
  }
});

export default router;

路由呢每次路由切换都会执行版本检查,可能会增加一定的延迟。

也可以使用轮询 setInterval(checkForUpdates, 3600000),但是消耗资源过大,但是也大不了多少,仁者见仁。。。

当然也可以使用WebSocket但是需要服务端支持。

​

相关推荐
小码哥_常4 小时前
一套自己部署的 IM,客户端是同一份 Flutter
前端·后端
蜗牛攻城狮6 小时前
微前端四大方案选型对比与最佳实践:qiankun、micro-app、wujie、Module Federation
前端·微前端·qiankun·前端架构·micro-app·wujie
她说可以呀8 小时前
Vue插槽
前端·javascript·vue.js
qq_448011168 小时前
Vue + Jinja2两套模版与法冲突造成undefinedError
前端·javascript·vue.js
aixingpan8 小时前
aixingpan.cn API开发文档:前端查询夏令时和时区接口指南
前端·php
2601_958352909 小时前
23.5×19mm 换掉一整条音频链?|A-68 集成了什么:ADC / DAC / 24.576MHz 时钟 / AEC / 波束降噪,主控仅需 6 根线
前端·音视频·ai降噪·回声消除·语音模块
志尊宝9 小时前
AI原生前端开发(039):AI辅助的Nuxt 4全栈开发
前端·vue.js·ai-native
FRing0310 小时前
JavaScript入门到精通三十二(深拷贝、浅拷贝、递归函数)
开发语言·前端·javascript
excel10 小时前
双 Token 与前端使用 Crypto 公私钥鉴权换 Token,哪种方案更好?
前端·后端
外收内放10 小时前
Python基础语法练习题(73)
java·前端·python