我正在尝试将服务工作者添加到在应用程序下运行的我们网站的一部分,除了主页没有尾部斜杠之外,它都可以正常工作 - 它将缓存页面但不会下载任何资产,除非我添加斜杠到url(我不能这样做,因为实时环境将其删除)
我已将服务工作者允许的标头添加到应用程序的站点:
<add name="Service-Worker-Allowed" value="/app-name" />
并更改范围以允许无斜杠 url:
// APP_NAME is global for app-name
navigator
.serviceWorker
.register(`/${APP_NAME}/service-worker.js`, { scope: `/${APP_NAME}` });
这很有效,因为我可以浏览到http://localhost/app-name
离线,但它没有任何 css、js 或图像。
如果我浏览到http://localhost/app-name/
我可以看到缓存已更新所有文件。有没有办法让服务人员在没有斜杠的情况下下载主页的文件?
服务工作者代码:
(() => {
'use strict';
const APP_NAME = 'app-name'; // define this as not compiled with webpack so no global
const version = 1;
const cacheName = `${APP_NAME}-cache`
const cacheNameWithVersion = `${cacheName}-${version}`
const offlineUrl = `/${APP_NAME}/offline`;
const urlsToCache = [
`/${APP_NAME}`,
offlineUrl,
];
const urlsToIgnore = [
'google-analytics.com',
'googletagmanager.com',
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(cacheNameWithVersion)
.then(cache => {
return cache.addAll(urlsToCache);
})
// Force the waiting service worker to become the active service worker.
.then(self.skipWaiting())
);
});
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys()
.then(keys => {
// Remove caches whose name is no longer valid
return Promise.all(keys
.filter(key => {
return key.indexOf(cacheName) === 0 && key.indexOf(cacheNameWithVersion) === -1;
})
.map(key => {
return caches.delete(key);
})
);
})
);
});
self.addEventListener('fetch', event => {
// don't load assets from these urls
for (let i = 0; i < urlsToIgnore.length; i++) {
if (event.request.url.indexOf(urlsToIgnore[i]) > -1) {
return;
}
}
if (event.request.method !== 'GET') {
// Always fetch non-GET requests from the network
event.respondWith(
fetch(event.request)
.catch(() => {
return caches.match(offlineUrl);
})
);
return;
}
// Only fetch non-GET requests offline
if (event.request.url.match(/\.(jpe?g|png|gif|svg)$/)) {
// handle images or show offline svg if image isn't cached
event.respondWith(
caches.match(event.request)
.then(response => {
return response || fetch(event.request)
.then(response => {
addToCache(event.request, response);
return response || serveOfflineImage();
})
.catch(() => {
return serveOfflineImage();
});
})
);
} else if (event.request.mode === 'navigate' || event.request.method === 'GET') {
// handle pages and assets like js and css
event.respondWith(
fetch(event.request)
.then(response => {
// Stash a copy of this page in the cache
addToCache(event.request, response);
return response;
})
.catch(() => {
return caches.match(event.request)
.then(response => {
return response || caches.match(offlineUrl);
});
})
);
}
});
function addToCache(request, response) {
if (!response.ok && response.type !== 'opaque')
return;
const copy = response.clone();
caches.open(cacheNameWithVersion)
.then(cache => {
if (!/^https?:$/i.test(new URL(request.url).protocol)) return;
cache.put(request, copy);
});
}
function serveOfflineImage() {
return new Response('<svg role="img" aria-labelledby="offline-title" viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg" class="object-fit"><title id="offline-title">Offline</title><g fill="none" fill-rule="evenodd"><path fill="#D8D8D8" d="M0 0h400v300H0z"/><text fill="#9B9B9B" font-family="Roboto,Arial,sans-serif" font-size="72" font-weight="bold"><tspan x="93" y="172">offline</tspan></text></g></svg>', { headers: { 'Content-Type': 'image/svg+xml' } });
}
})();