web 开发中,前端部署更新后,该怎么通知用户刷新
web 开发中,前端部署更新后,该怎么通知用户刷新?
- 浏览器为什么存在刷新按钮?🔘
- 因为需要重新加载js,css,html。但为何需要重新加载这些东西?
- 直白点说这些东西其实就是一个文档,一个特殊格式的文件而已,或者叫做资源一般来说文档这种东西是不会变,更不会频繁更改,所以浏览器有了缓存这个机制。
- 但是现代生产中,因为业务需求以及各种原因。需要频繁的更改 web 文件,或者采用前后端分离模式, spa 模式的开发,更不会让浏览器频繁的去触发
reload mod(重新加载模式)(这是一种加载策略)
去加载新的 web 静态资源。 - 所以更新完前端之后,我们都会主动,手动的去刷新一下页面,加载新的 web 静态资源。
解决思路:
- 在 public 中新建一个manifest.json 文件,写入一段json记录
{"version": "null", "buildDate":"null-null" }
- 在打包 build的时候修改此文件 记录 build时间和版本并放放置到 dist 文件夹下,代码示例如下;
update-manifest.js
const fs = require('fs');
const path = require('path');// 获取版本号和构建日期
const pkg = require('./package.json');
const version = pkg.version;
const buildDate = new Date().toISOString();// 定义源文件和目标文件的路径
const sourcePath = path.resolve(__dirname, 'public/manifest.json');
const destPath = path.resolve(__dirname, 'dist/manifest.json');// 读取源文件
fs.readFile(sourcePath, 'utf8', (err, data) => {if (err) {console.error('读取 manifest.json 失败:', err);return;}try {// 解析 JSON 数据const json = JSON.parse(data);// 修改内容json.version = version;json.buildDate = buildDate;// 将更新后的内容写入目标文件fs.writeFile(destPath, JSON.stringify(json, null, 2), 'utf8', (err) => {if (err) {console.error('写入 manifest.json 失败:', err);return;}console.log('manifest.json 已成功更新并写入到构建目录。');});} catch (parseErr) {console.error('解析 manifest.json 失败:', parseErr);}
});
package-lock.json,构建时执行node update-manifest.js
"scripts": {"serve": "vue-cli-service serve","build": "vue-cli-service build && node update-manifest.js"},
-
web 运行阶段,在前置路由守卫🪝函数中,去请求对比这个字段,不需要后端支持即可完成对新旧资源的标记对比。
-
基于
ETag
的更新检测 ,即HTTP ETag(实体标签)
是服务器为某一资源生成的唯一标识,用于判断资源是否发生变化。 -
利用
fetch
对带有版本戳的manifest.json
发起HEAD
请求,可以仅获取响应头而不下载完整文件,并从中读取ETag
-
ETag
本身只是一个http服务器
定义的、用来标识资源版本的“指纹”,通常是对文件内容或最后修改时间做 Hash 计算得出。只要资源有任何字节级的变化(比如buildDate
字段),ETag
就会不同。
const response = await fetch('/manifest.json', { method: 'HEAD' });const newEtag = response.headers.get('ETag');if (lastEtag && newEtag !== lastEtag) {// 资源已更新,提示用户刷新alert('应用已更新,请刷新页面以获取最新内容。');}lastEtag = newEtag; //类似:W/"2f-MF1DC3HLp40L8jDZQxcReJxdlZA"
} catch (error) {console.error('检查更新时出错:', error);
}
当然其他方案也可以:
- 比如通过
copy-webpack-plugin
插件的配置✅ - 通过静态资源哈希/版本文件比对✅
- Service Worker 更新通🈯️
- 后端响应头注入版本号(需要后端配合支持)
- 等等解决方案……