首页 > 解决方案 > 使用 apache 别名的服务工作者不起作用

问题描述

我想添加服务工作者来缓存我的应用程序中加载的资源。

假设我的应用程序正在https://domain/application下加载

从该 /application 页面,我正在从服务器别名 https://domain/mat-resources/applications/application1/dist/获取资源。

这是我的登记簿,

if (navigator.serviceWorker) {

    navigator.serviceWorker.register('/mat-resources/applications/application1/
/service-worker.js', {scope: '/mat-resources/applications/application1/'}).then(function (registration) {
            console.log("registration", registration);
    }).catch(function (e) {
        console.log(e);
    });
} else {
    console.log('Service Worker is not supported in this browser.')
}

这是我添加到 service worker js 的代码

'use strict';

const VERSION = 'v1';
const PRECACHE = `precache-${VERSION}`;
const RUNTIME = `runtime-${VERSION}`;
const enableRuntimeCache = true;
const mode = 'cache-update';

const PRECACHE_URLS = [
    'https://fonts.googleapis.com/css?family=Open+Sans:400,600|Roboto:400,500',
    './dist/js/vendor.bundle.js',
    './dist/js/app.bundle.js',
    './dist/css/styles.min.css'

];

let NetworkOnline = true;


self.addEventListener('install', event => {
    event.waitUntil(
        caches.open(PRECACHE).then(cache => {
            cache.addAll(PRECACHE_URLS);
        }).then(self.skipWaiting())
    );
});

self.addEventListener('activate', event => {

    const currentCaches = [PRECACHE, RUNTIME];
    event.waitUntil(
        caches.keys().then(cacheNames => {
            return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));
        }).then(cachesToDelete => {
            return Promise.all(cachesToDelete.map(cacheToDelete => {
                return caches.delete(cacheToDelete);
            }));
        }).then(() => {
            self.clients.claim();
        })
    );

});


self.addEventListener('fetch', event => {

    if (event.request.url.startsWith(self.location.origin)) {
        event.respondWith(fromCache(event.request));

        if (isOnline()) {
            if (mode === 'cache-update') {
                event.waitUntil(
                    update(event.request)
                    /*.then(refresh)*/
                    .catch(errorHandler)
                );
            }
        }
    }

});

/*function setFromCache(request) {

    console.log(self);
    updateFromCache(true);
}*/

function fromCache(request) {
    return caches.match(request).then(cachedResponse => {
        if (cachedResponse) {
            return cachedResponse;
        }

        if (isOnline()) {
            if (enableRuntimeCache) {
                return caches.open(RUNTIME).then(cache => {
                    return fetch(request).then(response => {
                        return cache.put(request, response.clone()).then(() => {
                            return response;
                        });
                    }).catch(errorHandler);
                });
            } else {
                return fetch(request).then(response => {
                    return response;
                });
            }
        }

    });
}

function update(request) {
    let asset = request.url.substr(request.url.lastIndexOf('/') + 1);
    let openCache = (PRECACHE_URLS.some(val => val.indexOf(asset) >= 0)) ? PRECACHE : RUNTIME;

    return caches.open(openCache).then(cache => {
        return fetch(`${request.url }?${new Date().valueOf()}`).then(response => {
            return cache.put(request, response.clone()).then(() => {
                return response;
            });
        }).catch(errorHandler);
    });
}


function refresh(response) {
    return self.clients.matchAll().then(clients => {
        clients.forEach(client => {
            var message = {
                type: 'refresh',
                url: response.url,
                eTag: response.headers.get('ETag')
            };

            client.postMessage(JSON.stringify(message));
        });
    });
}

function isOnline() {
    return self.navigator.onLine;
}

function errorHandler(error) {
    if (error instanceof TypeError) {
        if (error.message.includes('Failed to fetch')) {
            console.error('(FtF) Error caught:', error);
        } else {
            console.error('Error caught:', error);
        }
    }
}

成功刷新 Service Worker 后,我可以看到 Service Worker 已很好地注册,但资源并没有受到影响。

请帮忙??

标签: javascriptaliasservice-workerprogressive-web-apps

解决方案


您在注册服务人员时已经定义了一个范围。/mat-resources/applications/application1/**/*这将服务工作者的访问限制为仅处理针对路径下资源的提取

{scope: '/mat-resources/applications/application1/'}

如果您希望服务工作者在应用程序的根目录处理资源,/application您需要将范围设置为/.

{scope: '/'}

您可以在Web Fundamentals上阅读有关范围的更多信息。


推荐阅读