【问题标题】:Change precaching URL's / Service Worker scope更改预缓存 URL/Service Worker 范围
【发布时间】:2019-11-25 14:32:18
【问题描述】:

我正在尝试使用 Workbox 和 Gulp 构建一个服务工作者,它可以预缓存特定资产,但是,我遇到了一个问题,即注入到预缓存清单中的 URL 无效。

我相信这是由于 service-worker 的范围,因为它位于根目录中,我希望它缓存“公共”目录中的所有内容。我希望我的 URL 为 public/assets/image_1.png,但它们作为 assets/image_1.png 添加到预缓存清单中,并且 assets 文件夹之外的任何内容都将被忽略。

我可以通过将service-worker.js 添加到公共目录中来更正 URL,但随后服务工作者不会在浏览器中提供服务。我尝试在 Gulp 中操作 globPatterns,但这会引发语法错误。

以前有人遇到过这个问题吗?我是服务人员的新手,还没有找到任何可以帮助我解决问题的文章/GitHub 页面/SO 帖子,因此非常感谢任何帮助。希望这一切都对某人有意义。

目录:

.
+-- gulpfile.js
+-- package.json
+-- service-worker.js
+-- index.php
+-- public
|   +-- style.css
|   +-- script.js
|   +-- assets
|       +-- image_1.png
|       +-- image_2.png
+-- pwa
|   +-- dev-service-worker.js

gulpfile.js

gulp.task('service-worker', () => {
    return workboxBuild.injectManifest({
        swSrc: 'pwa/dev-service-worker.js',
        swDest: 'service-worker.js',
        globDirectory: 'public',
        globPatterns: [
            '**\/*.{js,css,html,png,jpg,jpeg,woff2,ttf,eot,svg}',
        ]
    }).then(({count, size, warnings}) => {
        // Optionally, log any warnings and details.
        warnings.forEach(console.warn);
        console.log(`${count} files will be precached, totaling ${size} bytes.`);
    });
});

service-worker.js

try {

    importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.2.0/workbox-sw.js');

    const LOCATION_ORIGIN = self.location.origin;
    const PRECACHE_PREFIX = "test";
    const PRECACHE_NAME = "precache";
    const PRECACHE_SUFFIX = "v2";
    const WORKBOX_PRECACHE = `${PRECACHE_PREFIX}-${PRECACHE_NAME}-${PRECACHE_SUFFIX}`;

    const URL_RULES = {
        "page-required": [
            'public/'
        ],
        "page-denied": [
            "\/some", "\/denied", "/^\/urls/"
        ],
        "static-required": [
            /\.(?:js,css,html,png,jpg,jpeg,woff2,ttf,eot,svg)$/
        ],
        "static-denied": [
            "\/some", "\/denied", "/^\/urls/"
        ]
    };

    if(workbox) {
        workbox.setConfig({ debug: true });

        workbox.clientsClaim();
        workbox.skipWaiting();

        workbox.core.setCacheNameDetails({
            prefix: PRECACHE_PREFIX,
            suffix: PRECACHE_SUFFIX,
            precache: PRECACHE_NAME
        });

        workbox.precaching.precacheAndRoute([]);

        workbox.routing.registerRoute(matchPage, serveOfflinePage);

        workbox.routing.registerRoute(
            matchStaticResource,
            workbox.strategies.cacheFirst({
                cacheName: 'test-runtime-cache',
                plugins: [
                    new workbox.expiration.Plugin({
                        maxAgeSeconds: 1 * 24 * 60 * 60 // 1 day
                    })
                ]
            })
        );

        function matchPage({ url }) {
            return URL_RULES["page-required"].every(pattern => matchPattern(url.pathname, pattern))
            && !URL_RULES["page-denied"].some(pattern => matchPattern(url.pathname, pattern));
        }

        function serveOfflinePage({ url, event }) {
            return fetch(event.request)
            .then(response => {
                if (response.status === 401) {
                    self.registration.unregister()
                    .then(() => self.clients.matchAll())
                    .then(clients => {
                        clients.forEach(client => client.navigate(client.url))
                    })
                    .catch(error => console.log(`Unable to authenticate and/or reload: ${error}`))
                }
                return response;
            })
            .catch(error => {
                return caches.open(WORKBOX_PRECACHE)
                .then(cache => {
                    return cache.match('/offline.html')
                    .then(response => response)
                })
            });
        }

        function matchStaticResource({ url }) {
            return url.href.indexOf(LOCATION_ORIGIN) !== -1 &&
            URL_RULES["static-required"].every(pattern => matchPattern(url.pathname, pattern)) &&
            !URL_RULES["static-denied"].some(pattern => matchPattern(url.pathname, pattern));
        }

        function matchPattern(urlPath, pattern) {
            if (typeof pattern === "string") {
                return urlPath.indexOf(pattern) !== -1;
            } else if (pattern instanceof RegExp) {
                return pattern.test(urlPath);
            }
        }
    }

} catch(e) {
    // Prevent caching logic on fail (mainly protecting against importScripts() failure)
}

【问题讨论】:

    标签: service-worker progressive-web-apps workbox


    【解决方案1】:

    我的答案是在我的 Gulpfile 中设置更多的绝对路径。 我为 root 添加了./,然后给了我的globPatterns 一个不同的路径。

    最后这是一个简单的解决方法,所以我将把它留在这里,以防其他人遇到类似问题。

     swSrc: './pwa/dev-service-worker.js',
     swDest: './service-worker.js',
     globDirectory: 'public',
     globPatterns: [
         '**\/public\/**\/*.{js,css,html,png,jpg,jpeg,woff2,ttf,eot,svg}',
     ]
    

    【讨论】:

      猜你喜欢
      • 2019-10-08
      • 2016-06-17
      • 1970-01-01
      • 2020-12-06
      • 1970-01-01
      • 1970-01-01
      • 2016-02-09
      相关资源
      最近更新 更多