目的
- 当网页更新功能时可以实时告诉网站用户有新版本可用
- 当修复bug时可以让用户及时刷新页面
可行性
目测两个网站已有此功能,可以实现
实现方法
- 方案 1:可以在接口里面带上版本号或 requestId 这种唯一标识符,不是最新版本提示用户刷新
- 方案 2: [https://github.com/ant-design/ant-design-pro/issues/2803#issue-378594750](
- 参考: [https://segmentfault.com/q/1010000039658752]
我将采用方案1实现,需后端配合。
实现过程
- 后端同事配合实现接口过滤器,每个接口都在 response-header 中返回
version
。这里需注意,非标准的响应头需要设置在Access-Control-Expose-Headers
中
httpServletResponse.setHeader("Access-Control-Expose-Headers", "version");
httpServletResponse.setHeader("version", version);
- 后端同事提供一个可以修改version的接口,前端通过调用这个接口来设置version
- 前端在接口response拦截器中获取版本号(此处用的 umi-request)
// 网站版本号
let versionCache: string | null = null;
let updateVersion: boolean = true;
request.interceptors.response.use(
(response) => {
const version = response.headers.get('Version') || response.headers.get('version');
if (versionCache && version && versionCache !== version && updateVersion) {
// 提示用户刷新页面
updateVersion = false;
showUpdateVersionModal();
}
if (!versionCache) {
versionCache = version;
}
return response;
},
{ global: true },
);
- 判断前后两次版本不一致时弹出弹窗
import React, { useEffect, useState } from 'react';
import ReactDOM from 'react-dom';
import { Modal } from 'antd';
type UpdateVersionModalType = {
show: (dom?: HTMLElement | null) => void;
instance: HTMLElement | null;
hide: () => void;
parent: HTMLElement | null;
} & React.FC<{
visible?: boolean;
}>;
const UpdateVersionModal: UpdateVersionModalType = (props) => {
const { visible: visibleProp = false } = props;
const [visible, setVisible] = useState<boolean>(false);
useEffect(() => {
setVisible(visibleProp);
}, [visibleProp]);
const onCancel = () => {
setVisible(false);
};
const onOk = () => {
window.location.reload();
};
return (
<Modal
visible={visible}
title="更新"
closable={false}
onCancel={onCancel}
onOk={onOk}
okText="立即刷新"
cancelText="取消"
maskClosable={false}
>
<p>检测到版本更新,刷新页面即可查看内容,不刷新可能会造成部分内容出错</p>
</Modal>
);
};
UpdateVersionModal.instance = null;
UpdateVersionModal.parent = null;
UpdateVersionModal.show = function (parentDom?: HTMLElement | null) {
if (!UpdateVersionModal.instance) {
UpdateVersionModal.instance = document.createElement('div');
UpdateVersionModal.parent = parentDom || document.body;
UpdateVersionModal.parent.appendChild(UpdateVersionModal.instance);
}
ReactDOM.render(<UpdateVersionModal visible />, UpdateVersionModal.instance);
};
UpdateVersionModal.hide = function () {
const { instance } = UpdateVersionModal;
if (instance) {
ReactDOM.render(<UpdateVersionModal visible={false} />, UpdateVersionModal.instance);
}
};
const showUpdateVersionModal = UpdateVersionModal.show;
const hideUpdateVersionModal = UpdateVersionModal.hide;
export { showUpdateVersionModal, hideUpdateVersionModal };
export default UpdateVersionModal;
如何更新
我司使用流水线部署代码,所以在流水线的部署步骤后面加了个额外的步骤,用来执行更新版本号的js代码,用node命令执行js代码即可调用代码。如果没有部署步骤,也可以在打包完毕后执行更新版本号的js代码
实际效果
若网页版本更新了,那么当老页面的用户调用了任意接口后,就会弹出弹窗