我发现此解决方案适用于 iOS Safari 和其他浏览器...
每当它检测到缓存的 Web 应用程序或网页与服务器的版本不匹配时,它会执行 window.location.reload(true) 强制页面重新加载以避免使用缓存。
您确实希望在发布您的网站的第一个版本之前使用此机制,否则一旦发布,您将无法再依赖永远升级您的 iOS 用户.如果您依赖客户端应用程序和服务器版本同步,这将是一场噩梦。 叹息 ...可悲的是,Safari 和 iOS Safari 似乎特别渴望take the throne once held by Internet Explorer。
部署期间
- 增加并保存内部版本号。
- 我使用一个看起来像
{"major":1,"minor":0,"patch":0,"build":12} 的 version.json 文件
- 将
version.json 复制到客户端和服务器应用程序。
在服务器上:
- 用 PHP/Node/Ruby/C# 编写一个服务器 API,返回服务器的
version.json
- 使用 Web 服务器规则和响应标头来防止 API 结果被缓存。
在客户端应用或网页中:
- 要诊断问题,请显示客户端版本 + 客户端和服务器内部版本号。
页面加载时调用...
function onload() {
var clientVersion = require("./version.json");
// Might replace axios with new fetch() API or older XMLHttpRequest
axios.get("/api/version").then(function(res) {
var serverVersion = res.data;
var lastReload = parseInt(localStorage.getItem("lastReload") || "0");
var now = new Date().getTime();
if (
serverVersion.build !== clientVersion.build &&
now - lastReload > 60 * 1000 // Prevent infinite reloading.
) {
localStorage.setItem("lastReload", now);
window.location.reload(true); // force page reload
}
});
}
您可能更喜欢测试serverVersion.build > clientVersion.build 而不是serverVersion.build !== clientVersion.build。测试!== 的好处在于,它不仅可以让您升级版本,还可以回滚版本并确保客户端也能回滚。
如果客户端和服务器内部版本号不匹配,我会通过仅在 60 秒内执行一次重新加载来防止客户端无限重新加载。
请注意,此方法仅与匹配的内部版本号(= 部署号)有关,您可能更喜欢更复杂的东西。
这是一个用于增加内部版本号的简单节点应用程序。
const APP_DATA = "../app/src/assets"; // client folder
const FUNC_DATA = "../functions/data"; // server folder
var log = require("debug")("build:incr");
var fs = require("fs");
function readJson(path) {
log(`Reading: ${path}`);
const text = fs.readFileSync(path);
return JSON.parse(text);
}
function writeJson(path, json) {
log(`Writing: ${path}`);
fs.writeFileSync(path, JSON.stringify(json));
}
let version = readJson("./version.json");
version.build++;
log("Version = ", version);
writeJson("./version.json", version);
writeJson(`${APP_DATA}/version.json`, version);
writeJson(`${FUNC_DATA}/version.json`, version);