版本校验方案
主要场景:
- 主要应对微信内网页缓存严重问题(加时间戳的,需要手动刷新一次。未加时间戳的,大概需要刷新三次。)
- 版本更新后,客户端再次打开,默认调用缓存,需要手动刷新
- 应对部分活动项目,频繁发版导致的缓存不更新问题
- 应对在线项目可能存在的,需要紧急全网修改的问题。[真有]
目标
- 版本更新后,用户无需刷新,无感知,自动刷新缓存
方案策略
- 在 version.json 文件中,存储当前版本 { "version": '1.0.1' }
- 在 check.js 中保存当前版本 var version = '1.0.1'
- 在 html 头部加载 check.js
- check.js 请求 version.json。request('xxxx/version.json?date=' + Date.now()),version.json是静态资源,加时间戳避免使用缓存
- check.js 请求到的 version 和 本地的不一致时,说明本地使用的是缓存,则刷新缓存 location.reload(true)
- 原生项目的话,最好也手动给改动的文件加上时间戳或者版本号
方案代码
index.html, safe/version.json, safe/check.js 三处的版本号需保持一致
index.html
<head>
<script src="./static/safe/check.js?version=1.0.0" type="text/javascript"></script>
</head>
safe/check.js
;(function() {
var version = '1.0.0'
function request(option) {
if (String(option) !== '[object Object]') return undefined
var xhr = new XMLHttpRequest()
xhr.responseType = option.responseType || 'json'
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
if (option.success && typeof option.success === 'function') {
option.success(xhr.response)
}
} else {
if (option.error && typeof option.error === 'function') {
option.error()
}
}
}
}
xhr.open(option.method || 'GET', option.url, true)
xhr.send()
}
var jsLoaded = document.scripts;
var currentJs = jsLoaded[jsLoaded.length - 1].src;
var safeUrl = currentJs.substring(0, currentJs.lastIndexOf('/')) + '/version.json?date=' + Date.now()
request({
method: 'GET',
url: safeUrl,
success: function (res) {
if (res.version !== version) {
location.reload(true)
}
},
error: function () { }
})
})();
safe/version.json
{
"version": "1.0.0"
}
- 原生项目的话,上面两个文件就可以了
使用构建方案
以 vue + webpack 为例
package.json, index.html, safe/version.json, safe/check.js 四处的版本号需保持一致
npm install --save-dev version-bump-prompt
package.json
"version": "1.0.0",
"scripts": {
"tag": "bump --prompt --grep index.html static/safe/version.json static/safe/check.js"
}
运行npm run tag
自动更新版本号,手动选择版本模式
说明
- 微信内会对
未加版本号
的文件强制缓存,reload 也无法更新,只能手动右上角刷新。 - 所以需要在
safe/check.js?version=1.0.0
后面加上版本号。 - HTML文件内,可能还引用了其它有版本号链接,例如 微信jsSDK。如果版本数字吻合的话,会被同步更改,这里要注意