【问题标题】:Blazor - Service worker not installing due to integrity check failureBlazor - 由于完整性检查失败而未安装服务工作者
【发布时间】:2022-08-02 19:51:31
【问题描述】:

我正在尝试为我的 blazor 应用程序设置 PWA。我按照以下说明操作:https://docs.microsoft.com/en-us/aspnet/core/blazor/progressive-web-app?view=aspnetcore-6.0&tabs=visual-studio

但是当我打开已部署的网站时,会出现以下错误:

Failed to find a valid digest in the \'integrity\' attribute for resource \'domain/manifest.json\' with computed SHA-256 integrity \'uDWnAIEnaz9hFx7aEpJJVS1a+QB/W7fMELDfHWSOFkQ=\'. The resource has been blocked.
Unknown error occurred while trying to verify integrity.
service-worker.js:22 
    
   Uncaught (in promise) TypeError: Failed to fetch
at service-worker.js:22:54
at async onInstall (service-worker.js:22:5)

在源文件中,这发生在这里:

async function onInstall(event) {
    console.info(\'Service worker: Install\');

    // Fetch and cache all matching items from the assets manifest
    const assetsRequests = self.assetsManifest.assets
        .filter(asset => offlineAssetsInclude.some(pattern => pattern.test(asset.url)))
        .filter(asset => !offlineAssetsExclude.some(pattern => pattern.test(asset.url)))
        .map(asset => new Request(asset.url, { integrity: asset.hash, cache: \'no-cache\' }));
    await caches.open(cacheName).then(cache => cache.addAll(assetsRequests));

}

我认为错误正在发生,因为 assetsRequests 中的条目具有错误的哈希并且资源被阻止。如果我从 service-worker-assets.js 中删除该文件,则会安装 service worker 并且可以使用 PWA。但我认为这不是一个可靠的解决方案。

appsettings.json 有时也会发生这种情况。在 service-worker-assets.js 中,我可以找到以下条目:

{
  \"hash\": \"sha256-+Py0\\/ezc+0k1sm\\/aruGPrVhS1jOCTfPKMhOSS+bunek=\",
  \"url\": \"manifest.json\"
},

所以哈希似乎不匹配。浏览器从哪里获取错误的哈希值?我该如何解决这个问题,使其匹配?

此外,该应用程序似乎有时会缓存旧文件。即使我在 Chrome 中执行“重置缓存和硬重新加载”,service-worker.js 文件仍然是旧版本。知道如何解决这个问题,因为它可能是相关的?

编辑:我也在检查这个解决方案:https://stackoverflow.com/a/69935118/11385442。但是在提到的 blazor.boot.json 中,我找不到对 manifest.json 或 appsettings.json 的任何引用。仅列出 Dll。所以问题似乎只与 blazor.boot.json 中未列出的文件有关。

Edit2:我在网络服务器上看到的是发布了以下文件:

appsettings.json
appsettings.json.br
appsettings.json.gzip

所以似乎添加了压缩版本。此外,appsettings.json 的大小与解决方案中的大小不同。我的猜测是,在构建或发布管道(Azure)的某个地方,文件被修改了。但即使我将 appsettings.json 手动复制到网络服务器,错误仍然会发生。我正在关注此处提供的信息:https://docs.microsoft.com/en-us/aspnet/core/blazor/host-and-deploy/webassembly?view=aspnetcore-5.0 (诊断完整性问题)

  • 我只是在我自己的项目中修复了 PWA 缓存 Blazor 问题。我遵循这个 tuto:whuysentruit.medium.com/… 此外,我还需要做一些小修改:github.com/dotnet/aspnetcore/issues/… 现在看来工作正常 :)
  • 您知道与您的第一次实施相比,实际的修复或不同之处是什么吗?我也试过 {updateViaCache: \'none\'} 但现在它给我的 index.html 文件同样的错误。
  • @DylanBarquilla 我遵循相同的教程并进行了小修改。现在我可以在本地测试它。它似乎只有在我对文件进行更改时重建解决方案后才有效。看起来哈希没有以某种方式正确更新。
  • 如果你和我学过同样的教程,你应该有一个文件sw-registrator.js。在其中,我将navigator.serviceWorker.register(\'/service-worker.js\')[...] 替换为navigator.serviceWorker.register(\'/service-worker.js\', { updateViaCache: \'none\' })[...]。我认为它迫使 serviceWorker 尝试通过服务器进行更新,而不是使用缓存,这似乎很好。是否可以将所有来源放在某个地方,以便我检查一下? (至少 index.html、sw-registrator.js 和 service-worker.js (2) )
  • 我已经这样做了,代码完全相同。 sw-registrator 也在工作,但在 onInstall 中发生了相同的完整性错误(因为这与以前的代码相同)。我想这可能与我们的构建服务器如何构建和部署程序集有关。感谢您一直以来的帮助!

标签: javascript c# .net-core blazor progressive-web-apps


【解决方案1】:

我的猜测是对的。 appsettings.json 的修改可能是由于 azure 管道中的 xml 转换。我目前的解决方案是排除对此类资源的完整性验证,如以下答案中所述:Error loading appsettings.Production.json due to digest integrity issue

我还更改了原始帖子 cmets 中提到的“sw-registrator.js”以正常工作,因为这没有重新加载应用程序:

function invokeServiceWorkerUpdateFlow(registration) {
    if (confirm("New version available, reload?") == true) {
        if (registration.waiting) {
            console.info(`Service worker registrator: Post skip_waiting...`);

            // let waiting Service Worker know it should became active
            registration.waiting.postMessage('SKIP_WAITING')
        }
    }
}

function checkServiceWorkerUpdate(registration) {
    setInterval(() => {
        console.info(`Service worker registrator: Checking for update... (scope: ${registration.scope})`);

        registration.update();
    }, 60 * 1000); // 60000ms -> check each minute
}

// check if the browser supports serviceWorker at all
if ('serviceWorker' in navigator) {
    // wait for the page to load
    window.addEventListener('load', async () => {
        // register the service worker from the file specified
        const registration = await navigator.serviceWorker.register('/service-worker.js');

        // ensure the case when the updatefound event was missed is also handled
        // by re-invoking the prompt when there's a waiting Service Worker
        if (registration.waiting) {
            invokeServiceWorkerUpdateFlow(registration);
        }

        // detect Service Worker update available and wait for it to become installed
        registration.addEventListener('updatefound', () => {
            if (registration.installing) {
                // wait until the new Service worker is actually installed (ready to take over)
                registration.installing.addEventListener('statechange', () => {
                    if (registration.waiting) {
                        // if there's an existing controller (previous Service Worker), show the prompt
                        if (navigator.serviceWorker.controller) {
                            invokeServiceWorkerUpdateFlow(registration);
                        } else {
                            // otherwise it's the first install, nothing to do
                            console.log('Service worker registrator: Initialized for the first time.')
                        }
                    }
                });
            }
        });

        checkServiceWorkerUpdate(registration);

        let refreshing = false;

        // detect controller change and refresh the page
        navigator.serviceWorker.addEventListener('controllerchange', () => {
            console.info(`Service worker registrator: Refreshing app... (refreshing: ${refreshing})`);

            if (!refreshing) {
                window.location.reload();
                refreshing = true
            }
        });
    });
}
else
{
    console.error(`Service worker registrator: This browser doesn't support service workers.`);
}

我还必须在 service-worker.js 中添加这个:

self.addEventListener('message', (event) => {
    console.info('Service worker: Message received');
    if (event.data === 'SKIP_WAITING') {
        // Cause the service worker to update
        self.skipWaiting();
    }
});

这段代码主要取自https://whatwebcando.today/articles/handling-service-worker-updates/

【讨论】:

    猜你喜欢
    • 2018-08-16
    • 1970-01-01
    • 2020-06-29
    • 2023-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-10
    • 2023-04-10
    相关资源
    最近更新 更多