强制从Javascript全面刷新Blazor WebAssembly PWA应用程序



这段代码在index.html中。我用最新版本的Blazor WebAssembly PWA应用程序调用updateVersion。第一行是Blazor应用程序模板中服务人员的原始注册。其余由我添加。

navigator.serviceWorker.register('service-worker.js');
function updateVersion(newVersion) {
var key = 'x-photish-version';
var oldVersion = localStorage.getItem(key);
if (oldVersion == null) {
localStorage.setItem(key, newVersion);
}
else if (newVersion != oldVersion) {
localStorage.setItem(key, newVersion);
// Reload service worker
navigator.serviceWorker.register('service-worker.js').then(function (registration) {
caches.delete("blazor-resources-/").then(function (e) {
console.log("'blazor-resources-/' cache deleted");
});
registration.update();
window.location.reload(); 
}).catch(function (error) {
// registration failed
console.log(`Registration failed with ${error}`);
});
}
}

版本部分有效。它检测到版本是新的,并正确地输入了代码的newVersion != oldVersion部分,我想确保应用程序完全刷新。

为了测试它,我发布了一个新版本的应用程序,对我的应用程序进行了一些琐碎的更改,它会检测到它是新版本并重新加载页面。我的小应用程序更改不会出现。它显示了该应用程序的旧版本。

我必须从代码中找到一种方法来做到这一点,因为我不希望用户在每次加载页面时都检索到最新的内容。只有当我实际部署了新版本的代码时。

我该怎么做才能确保serviceworker被刷新,而blazor应用程序本身的缓存没有被缓存?

UPDATE:我原以为在将代码更改为以下内容后就解决了,但我仍然看到一些情况下它不起作用。

navigator.serviceWorker.register('service-worker.js');
function updateVersion(newVersion) {
var key = 'x-photish-version';
var oldVersion = localStorage.getItem(key);
if (oldVersion == null) {
localStorage.setItem(key, newVersion);
}
else if (newVersion != oldVersion) {
localStorage.setItem(key, newVersion);
caches.delete("blazor-resources-/").then(function (e) {
console.log("'blazor-resources-/' cache deleted");
});
// Reload service worker
navigator.serviceWorker.register('/service-worker.js', { updateViaCache: 'none' }).then(function (registration) {
window.location.reload(); 
}).catch(function (error) {
// registration failed
console.log(`Registration failed with ${error}`);
});
}
}

仍然希望有人能修复代码并使其防弹,或者简单地声明出于某种原因,这在技术上是不可能的。

我找到了一个解决方案,并在几天内确认它有效。它也适用于我的PWA加载到iOS。

如果与wwwroot/serviceworker.published.js.中更新的constCACHE相结合,我的现有函数就可以工作

我的后期构建Powershell脚本如下所示:

$currentDate = get-date -format yyyy.MM.dd.HHmm;
# Update service worker
$curDir = Get-Location
$inputFile = $curDir.Path +"wwwrootservice-worker.published.js"
$findString = "const CACHE_VERSION =.+"
$replaceString = "const CACHE_VERSION = '$currentDate'"
(Get-Content $inputFile) | ForEach-Object { $_ -replace $findString , $replaceString } | Set-Content $inputFile
Write-Host "Service Worker Updated:     $currentDate"

要使其工作,我必须手动将此行添加到serviceworker.published.js:

const CACHE_VERSION = '2022.08.10.2222'

我还使用下面的后构建Powershell脚本来更新version.txt中的版本,我一直知道它会更新。然后我还更新了csproj中的程序集版本。这样我就可以比较这两个值,看看我是否真的在运行最新的代码:

param([string]$ProjectDir, [string]$ProjectPath);
$currentDate = get-date -format yyyy.MM.dd.HHmm;
# Update version.txt
$versionFilePath = $ProjectDir + "/wwwroot/version.txt"
Set-Content -Path $versionFilePath -Value $currentDate -NoNewline
Write-Host "version.txt Updated:        $currentDate"
# Update actual assembly version
$find = "<Version>(.|n)*?</Version>";
$replace = "<Version>" + $currentDate + "</Version>";
$csproj = Get-Content $ProjectPath
$csprojUpdated = $csproj -replace $find, $replace
Set-Content -Path $ProjectPath -Value $csprojUpdated
Write-Host "Assembly Version Updated:   $currentDate"

为了供您参考,我在C#:中检查了这样的程序集版本

assemblyVersion = Assembly.GetExecutingAssembly()?.
GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.
InformationalVersion;

我用一个简单的http调用检查了最新版本,但表示C#中没有缓存

var message = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri(baseUri + "version.txt?nocache=" + DateTime.Now.ToString("yyyyMMddHHmmss"))
};
message.Headers.CacheControl = new CacheControlHeaderValue
{
NoCache = true
};
var versionResponse = await http.SendAsync(message);
var version = await versionResponse.Content.ReadAsStringAsync();
return version;

我用Blazor:中的这一行调用index.html中的函数

await js.InvokeAsync<string>("updateVersion", state.Version);

最后是index.html中的javascript,它将清除缓存并刷新服务工作者。

navigator.serviceWorker.register('service-worker.js');
function updateVersion(newVersion) {
var key = 'x-photish-version';
var oldVersion = localStorage.getItem(key);
if (oldVersion == null) {
localStorage.setItem(key, newVersion);
}
else if (newVersion != oldVersion) {
localStorage.setItem(key, newVersion);
caches.delete("blazor-resources-/").then(function (e) {
console.log("'blazor-resources-/' cache deleted");
});
// Reload service worker
navigator.serviceWorker.register('/service-worker.js', { updateViaCache: 'none' }).then(function (registration) {
window.location.reload(); 
}).catch(function (error) {
// registration failed
console.log(`Registration failed with ${error}`);
});
}
}

第一行包含在标准Blazor模板中。剩下的是从Blazor中的interop调用的函数。

沃伊拉:只是代码。每次生成时,都会更新版本号。如果用户打开过期的生产代码,页面将自动重新加载,然后运行最新的代码。

嘿,这对你有用,试试这个

window.updateAvailable = new Promise((resolve, reject) => {
if (!('serviceWorker' in navigator)) {
const errorMessage = `This browser doesn't support service workers`;
console.error(errorMessage);
reject(errorMessage);
return;
}
navigator.serviceWorker.register('/service-worker.js')
.then(registration => {
console.info(`Service worker registration successful (scope: ${registration.scope})`);
registration.onupdatefound = () => {
const installingServiceWorker = registration.installing;
installingServiceWorker.onstatechange = () => {
if (installingServiceWorker.state === 'installed') {
resolve(!!navigator.serviceWorker.controller);
}
}
};
})
.catch(error => {
console.error('Service worker registration failed with error:', error);
reject(error);
});
});
window.registerForUpdateAvailableNotification = (caller, methodName) => {
window.updateAvailable.then(isUpdateAvailable => {
if (isUpdateAvailable) {
caller.invokeMethodAsync(methodName).then();
}
});
};

也检查参考:https://gist.github.com/huysentruitw/24b23ec49ebd38c9ff891ffb83f06088#file-服务人员js

相关内容

  • 没有找到相关文章

最新更新