前后台分离的WEB应用项目上线时,会因浏览器的自动缓存策略而发生一些错误。比如项目的前后台同时由V1.0升级为了V1.1。此时由于浏览器缓存,用户在打开项目地址时仍然使用了缓存中的V1.0的代码。这便会发生V1.0的前台调用V1.1的后台的BUG。
本文以angular为例,阐述一种前台更新后项目浏览器自动刷新的解决方案。
本文示例代码地址:https://stackblitz.com/edit/angular-2k4qy2
基本思路
想实现前台如果更新后便重新强制浏览器刷新的功能,则需要加入一个版本号来进行控制。在系统启动时读取前台的版本号,然后与服务器上的版本号进行比对。如果版本号相同,则说明浏览器当前加载的前台与服务器提供的前台的版本是统一的,则什么也不做;如果版本号不同,则说明浏览器当前加载的版本与服务器提供的版本不统一,则强制浏览进行刷新以清除缓存带来的影响。
加入版本号
在项目的src/assets文件夹中新建config.json
,并加入以下信息以记录当前应用的版本号:
{
"version":"1.0.0"
}
线上演示的需求,我们必须将其建立在src/assets中。实际的生产项目中,可以将其按需建立在src文件夹下的任意位置。
获取版本号
若要对版本号进行比对,则需要获取两个版本号:第1个为WEB应用运行的版本号,第2个为服务器提供的WEB应用的版本号。
当这两个版本号不统一时,则说明当前运行的版本与服务器提供的版本不一致,便应进行强制刷新。
运行应用的版本号
export class AppComponent implements OnInit {
private config: {version: string}; ➊
ngOnInit() {
this.config = require('./../assets/config.json'); ➋
console.log(this.config.version);
}
}
- ➊ 声明config类型
- ➋ 使用require加载config.json文件,并将其值赋予this.config
服务器提供应用的版本号
export class AppComponent implements OnInit {
constructor(private httpClient: HttpClient) {
}
private config: {version: string};
ngOnInit() {
this.config = require('./../assets/config.json');
console.log(this.config.version);
this.httpClient.get<{version: string}>('/assets/config.json')
.subscribe(config => {
console.log(config);
}); ➊
}
}
- ➊ 获取config.json并打印
值得注意的是,在请求后台的config.json
时,浏览器最终调用的可能也是缓存的数据,这时候就需要在请求的header上做点文章,强制浏览器在请求config.json
时弃用缓存:
ngOnInit() {
this.config = require("./../assets/config.json");
console.log(this.config.version);
const headers = new HttpHeaders()
.set('Cache-Control', 'no-cache')
.set('Pragma', 'no-cache'); ➊
this.httpClient
.get<{ version: string }>("/assets/config.json", {headers➋})
.subscribe(config => {
console.log(config);
});
}
- ➊ 新建不使用缓存的header
- ➋ 在请求中加入header信息,此请求则不使用浏览器缓存
强制刷新当前页面
location中提供了reload(true)方法来进行页面的强制刷新:
.subscribe(config => {
if (config.version !== this.config.version) {
location.reload(true); ➊
}
});
- ➊ 强制刷新页面
但不知何种原因,该方法被标识为弃用。简单的查了一些资料,有人说这个方法可能在后面的版本中被浏览器弃用,于是使用以下代码进行页面刷新操作:
if (config.version !== this.config.version) {
this.httpClient
.get(""➊, { headers➋, responseType: "text"➌ })
.subscribe(() => location.reload()➍);
}
- ➊ 重新拉取首页
- ➋ 禁用缓存
- ➌ 响应类型为text
- ➍ 此时再进行reload操作,则浏览器即使调用了缓存,该缓存也是➊中拉取的服务器中最新的前台应用了。
总结
在前台后分离的应用中,自动的进行缓存的判断当有助于客服人员大幅的减轻压力,增强用户对系统的粘稠度。本文使用暴露前台的版本文件并进行比对的方法,来判断是否要强制刷新浏览器缓存;再结合httpClient发请对loading页的请求,以达到间接的强制刷新浏览器缓存的目的。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。