网站建设的第三方平台,网站建设的必要性,网络营销咨询公司,企业网页设计方案一、需求解析
为什么我会想到这个技术呢#xff0c;是因为我有一次发现#xff0c;我司的用户在使用网页的时候#xff0c;经常会出现一个页面放很久#xff0c;下班也不关这个页面#xff0c;这样就会导致页面的代码长时间处于不更新的状态。 在使用到一个功能出了bug是因为我有一次发现我司的用户在使用网页的时候经常会出现一个页面放很久下班也不关这个页面这样就会导致页面的代码长时间处于不更新的状态。 在使用到一个功能出了bug或者逻辑已经改变的情况报错了过来问我们为什么会报错我们花时间排查之后发现是因为代码没更新。其实这种错误完全是可以避免的我们要如何提醒用户代码已经更新了请更新版本呢?
二、需求思考过程
首先要达到让用户知道版本更新肯定需要弹出一个窗口提示用户版本更新请保存当前的工作内容并点击更新按钮进行更新操作。我们如何去设置每次发版的代码版本呢代码版本发布后我们又要如何检测到版本发生变化呢
三、难题解决
设置每次发版的代码版本
因为我比较少写jquery 等其他技术的前端在此就针对 vue react 等工程化的前端技术栈进行解析 每次我们在发布版本都会走一个步骤那就是 npm run build打包操作 我们需要在打包的时候给打包后的代码加上一个版本号我目前能想到两个方式实现 文件更新后的hash值 和 index.html 里面的 meta 简单说一下 hash值打包的设置那里我们可以设置每次打包后文件的hash值变动只有有一个hash值变了那么我们就可以理解为版本更新了但是这个我用的比较少在此做一个截图举例即可 以下着重介绍通过判断 index.html 的 meta去判断版本更新的方式 我们可以写一个node脚本在npm run build命令之后执行这个node脚本往我们打包后的dist文件夹里面的 index.html 文件插入一个 meta里面是我们的版本号脚本如下
const fs require(fs)/**版本号当前时间戳保证唯一 */
const versionNo new Date().getTime()
const htmlPath ./dist/index.htmlconst insertVersionMeta () {let html fs.readFileSync(htmlPath, utf-8)html html.replace(head, headmeta nameversion_no content${versionNo} /)fs.writeFileSync(htmlPath, html)
}insertVersionMeta()
以上代码的逻辑就是获取到打包后的dist/index.html 文件通过fs.readFileSync去读取到里面的内容然后往 head 里面插入一个 meta说明当前网页的版本号我这里用的是最简单的时间戳 如果想要达成我们想象中的 v1.0.0这种 x-y-z 的版本格式可以运行这个脚本的时候弹出像vue脚手架创建那种命令行输入的方式如 1-请问您本次版本更新是 a.小版本更新自动更新z1 b.大需求更新自动y1 c. 超大版本更新颠覆页面等这种(自动 x1) d. 自己输入版本号 2-请简单描述一下本次版本更新的内容 要达到这种效果就得加入inquirer等命令行的开源技术如果感兴趣我也可以后续对这个脚本进行优化加入这个效果。在此就先不展开 检测代码版本是否更新
检测是否更新我们只需要获取远程服务器的index.html 文件获取到里面我们设置好的 version_no 与我们当前网页的 version_no 做对比只要存在不同那么就代表版本更新了。在此我采用一个轮询的方式进行编写如果是已经引入webSocket项目也可以采用socket的方式进行通知
// App.vue
data() {return {// 轮询查询新版本timer: null,pollingTime: 1000 * 60 * 30 // 半小时},
created() {this.getCurrentVersion()this.fetchNewVersion()this.timer setInterval(() {this.fetchNewVersion()}, this.pollingTime)},
methods: {// 获取当前版本号getCurrentVersion() {const metaList document.querySelectorAll(meta)if (!metaList.length) returnfor (let i 0; i metaList.length; i) {const item metaList[i]if (item.name version_no) {this.version item.contentbreak}}},// 获取远程服务器的版本号async fetchNewVersion() {// 在 js 中请求首页地址不会更新页面const timestamp new Date().getTime()const response await axios.get(${window.location.origin}?time${timestamp})// 返回的是字符串需要转换为 htmlconst el document.createElement(html)el.innerHTML response.datalet newVersion // 拿到版本号const metaList el.querySelectorAll(meta)if (!metaList.length) returnfor (let i 0; i metaList.length; i) {const item metaList[i]if (item.name version_no) {newVersion item.contentbreak}}if (newVersion newVersion ! this.version) {this.$refs[NoticeNewVersion].open()}},
}
}弹窗版本更新通知
这一块就很简单了我们只需要写一个版本更新的组件让它弹出版本号 和 版本说明直接获取远程服务器的meta显示即可。
四、遇到的坑
我写好这个后发现一个问题每次弹出版本更新通知过了一会儿后会再次弹出但我并没有再次部署版本而且这个问题不是必现的有的人是好的有的人会一直弹出
后面发现原来是缓存的锅刷新后浏览器存在html的缓存304导致一直获取到是老的版本号那么每次轮询都会弹出版本更新。
如何解决呢只需要在nginx里面设置index.html不缓存即可
location / {expires 1h;root /home/html;index index.html index.htm;## html不缓存 if ($request_filename ~* .*\.(htm|html)$) {add_header Cache-Control no-store;}
}