前端重新部署后如何让用户刷新页面?

2022-05-26 19:08:18 +08:00
 kongkongye

目前碰到的情况是前端重新构建部署后,js 之类文件名都变了,前端点击另一个页面就白屏(控制台报错 js 文件找不到),而很多用户比较小白就会反馈页面出问题了而不是刷新页面。
所以想着重新部署后应该通知到用户应该刷新前端页面,目前能想到的方式是所有请求都自动加上前端当前版本,通过工具重新构建后通知后端修改前端最新版本号,然后前端页面请求时就能返回信息让前端提示页面需要刷新,不知有没更好的办法?

6829 次点击
所在节点    前端开发
50 条回复
gouflv
2022-05-27 00:24:03 +08:00
典型的 没找到原因就开始想解决方案
bjfane
2022-05-27 02:18:49 +08:00
哈哈哈,好巧,这是我面试题库里的题之一,我的方案是路由守卫里加实现,做法也很简单,/version.json 是发布时候的一个时间戳 - {202205234345564},beforeRoute 里有动作就请求 /version.json?{random},和当前程序里的 version 不一致就提示 并自动刷新

ws 和轮训都不太行,开销太大。
Puteulanus
2022-05-27 02:36:32 +08:00
我们是用的 ws ,脚本是在 nginx 里用 replace 直接注入到页面 html 里的,所以只有测试环境有,打开页面的时候会建一个到通知服务的连接,然后 pipeline 上一旦重新部署了会调一下通知服务,对所有当前连接用户广播一个通知过去

那种页面挂后边挺长时间甚至出门吃了个饭 ws 已经断了太久的,就给个提示说网页可能不是最新了

当时的需求是 QA 说可能测试环境布了新版本他们不知道,测出来的还是老版本前端的 bug ,特别是有了零停机部署之后,部署过程中服务是完全不中断的,所以做了个通知给当前正在使用网页的人
aaronlam
2022-05-27 06:11:43 +08:00
anguiao
2022-05-27 07:52:28 +08:00
你这个需求的话,不缓存 HTML (或者协商缓存),只缓存静态文件,不就行了么。
静态文件的文件名都是带 hash 的,只要 HTML 更新了,这些静态文件也会跟着更新。

我是用 nginx 的 request_filename 来做的,目前用下来没发现有什么问题。
zhuwd
2022-05-27 08:25:05 +08:00
@bjfane 这个方案是不是相当于每次路由跳转都要拉一下 version.json 文件?
ChefIsAwesome
2022-05-27 08:37:16 +08:00
动态加载 js 文件时会出现这种问题。最常见的就是做 spa ,并且每个路由的 js 是动态加载的。因为 { /path: xx.js } 这个是写在最初访问网页时下载的 js 里的。而 spa 切换页面时不会重新下载 html ,也就不会重新下载最初的 js 。
实际上这个问题等同于后端接口升级了,用旧版本客户端的人要怎么办。
原生应用一般就是保留旧版本的资源,再加一个检查版本,提示升级的功能。
网页跟原生应用不一样,不存在死守着旧版本不放的情况。保留一个旧版本就行了。
sugars
2022-05-27 08:42:45 +08:00
@anguiao 他的意思是不刷新页面啊,你这个不还得去刷新页面才能重新访问 index.html
anguiao
2022-05-27 08:52:48 +08:00
@sugars 确实,欠考虑了。
lower
2022-05-27 09:26:40 +08:00
@kongkongye 层主不是说了,在 error 的时候处理么,都 error 了,随便提示个网络连接异常啥的把用户哄过去……
DOLLOR
2022-05-27 09:27:00 +08:00
(await fetch(`./index.html?nocache=${Date.now()}`)).headers.get('last-modified')
cloverstd
2022-05-27 09:35:36 +08:00
你的问题是发布后,老的页面的 js 没法访问了,增量发布就行,不要删除老的文件,反正静态资源文件名有 hash
lerry
2022-05-27 09:36:23 +08:00
1. 可以不删除旧的资源文件避免报错
2. 打包时加入一个版本号,定时检测

"build": "vue-cli-service build && npm run update-version",
"update-version": "mkdir -p dist && echo `date +%s` > dist/version.txt"

设置一个定时器,检查版本号有没有变化,弹窗提示 reload
await fetch(`/version.txt?timestamp=${Date.now()}`);
hevi
2022-05-27 09:36:29 +08:00
下班的时候更新呗,又不愿意用 websocket 。
~~js 名字匹配重定向,曲线救国~~
wanguorui123
2022-05-27 10:13:04 +08:00
缓存设置短点 1 小时过期,开启 302 ETag 检查
bjfane
2022-05-27 11:42:28 +08:00
@zhuwd 是的,一个静态文件,但是内容很短
kongkongye
2022-05-27 12:20:39 +08:00
@lerry 我最后思考出的解决方案几乎跟你这一致
lizy0329
2022-05-30 18:45:32 +08:00
你傻啊,发布代码为什么要将之前的文件删掉?要做到非覆盖式发布,而不是覆盖式发布
a570295535
2022-06-01 22:02:05 +08:00
你可以在页面上写个 js 判断调用的 js 是否加载成功,成功就忽略,没成功就提醒用户,现在网页升级了,你是否刷新一下,不刷新就给老子滚!
a570295535
2022-06-01 22:57:40 +08:00
把这句加到其他 js 的前面:
<script type="text/javascript">window.addEventListener('error',function(){document.write("出错了二逼,<a href=\"javascript:location.reload();\">给爷刷新</a>");},true);</script>

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/855521

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX