微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Service Worker 无法在新的 chrome 窗口中启动

如何解决Service Worker 无法在新的 chrome 窗口中启动

我正在尝试使用 Service Worker 来缓存应用程序,但在 chrome 上似乎如果您启动一个新的 chrome 窗口加载网页并断开网络连接,它将无法拦截获取请求并且无法访问应用程序图像从缓存中。如果浏览器刷新,Service Worker 将启动并且应用程序正常加载。下面是一些工人的代码

/// <reference lib="webworker" />
/* eslint-disable no-restricted-globals */

// This service worker can be customized!
// See https://developers.google.com/web/tools/workBox/modules
// for the list of available WorkBox modules,or add any other
// code you'd like.
// You can also remove this file if you'd prefer not to use a
// service worker,and the WorkBox build step will be skipped.

import { clientsClaim } from 'workBox-core';
import { createHandlerBoundToURL,precacheAndRoute } from 'workBox-precaching';
import { registerRoute } from 'workBox-routing';

declare const self: ServiceWorkerGlobalScope;

console.log('SW code starting');

clientsClaim();

// Precache all of the assets generated by your build process.
// Their URLs are injected into the manifest variable below.
// This variable must be present somewhere in your service worker file,// even if you decide not to use precaching. See https://cra.link/PWA
precacheAndRoute(self.__WB_MANIFEST);

// Set up App Shell-style routing,so that all navigation requests
// are fulfilled with your index.html shell. Learn more at
// https://developers.google.com/web/fundamentals/architecture/app-shell
const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$');
registerRoute(
    // Return false to exempt requests from being fulfilled by index.html.
    ({ request,url }) => {
        // If this isn't a navigation,skip.
        if (request.mode !== 'navigate') {
            return false;
        } // If this is a URL that starts with /_,skip.

        if (url.pathname.startsWith('/_')) {
            return false;
        } // If this looks like a URL for a resource,because it contains // a file extension,skip.

        if (url.pathname.match(fileExtensionRegexp)) {
            return false;
        } // Return true to signal that we want to use the handler.

        return true;
    },createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html')
);

const BASE_PATH = '/app/client';

// All images in the assets folder should be here
const assetimageList = [
    //images
];

const assetIconList = [
    //icons
];

const assetsMisc = [BASE_PATH + '/assets/shapes.svg'];

const manifestAssets = [BASE_PATH + '/manifest.json',BASE_PATH + '/asset-manifest.json'];

const webWorkers = [BASE_PATH + '/webWorkers/dataDownloader.js',BASE_PATH + '/webWorkers/pouchdb-7.2.1.min.js'];

// Set the assets to store - NOTE* This version has to be updated per release to ensure the cached files are the latest client code
const cacheName = 'site-v1';
const assets = [BASE_PATH + '/',...assetimageList,...assetIconList,...assetsMisc,...manifestAssets,...webWorkers];
export const serviceWorkerAssetsExcludeBasePath = [...assetimageList,...webWorkers];

self.addEventListener('install',(installEvent) => {
    console.log('Install');
    installEvent.waitUntil(
        caches.open(cacheName).then((cache) => {
            cache.addAll(assets);
        })
    );
});

const workBoxCacheName = 'workBox-precache';
// The activate even generally used to do stuff that would have broken the prevIoUs version while it was still running,for example getting rid of old caches;
self.addEventListener('activate',(event) => {
    const cacheKeeplist = [cacheName];
    console.log('Activate');

    // Iterate over the caches and remove any that is not on the keep list
    event.waitUntil(
        caches.keys().then((keyList) => {
            return Promise.all(
                keyList.map((key) => {
                    if (cacheKeeplist.indexOf(key) === -1) {
                        // Careful here,we don't want to delete the workBox cache
                        if (!key.includes(workBoxCacheName)) {
                            console.log('deleteing ' + key);
                            return caches.delete(key);
                        }
                    }
                })
            );
        })
    );
});

console.log('Just before fetch code');
self.addEventListener('fetch',async (event) => {
    const clone = event.request.clone();
    console.log('fetch intercepted');
    if (serviceWorkerAssetsExcludeBasePath.some((assetUrl) => clone.url.includes(assetUrl))) {
        event.respondWith(
            caches.match(event.request).then(function (response) {
                console.log('Cached response found ' + (response && response!.url));
                return response || fetch(event.request);
            })
        );
    }
});

这是带有新 chrome 窗口的控制台输出。只触发注册,不启动worker。

chrome_new_window_console_output

这表明工人已停止。

chrome_worker_stopped


这是页面刷新后的输出。 Worker 启动并开始拦截请求。

chrome_after_refresh


那么这种行为是预期的吗?有没有办法确保每次加载页面时工作人员都启动?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。