问题
I can't get the offline.html page to display. I keep getting the The FetchEvent for "https://my-domain.com" resulted in a network error response: a redirected response was used for a request whose redirect mode is not "follow"
.
Here's the snippet of my service-worker.js which should return the offline.html
when the network is unavailable.
self.addEventListener('fetch', function(event) {
if (event.request.mode === 'navigate' || (event.request.method === 'GET' && event.request.headers.get('accept').includes('text/html'))) {
if(event.request.url.includes("my-domain.com")){
console.log(event.request);
event.respondWith(
caches.match(event.request).then(function(resp) {
return resp || fetch(event.request).then(function(response) {
let responseClone = response.clone();
caches.open(CACHE_NAME).then(function(cache) {
cache.put(event.request, responseClone);
});
return response;
});
}).catch(function() {
return caches.match("/offline.html");
})
);
}
}
});
Below is the console.log of my network request (page refresh when offline)
Request {method: "GET", url: "https://my-domain.com", headers: Headers, destination: "unknown", referrer: "", …}
bodyUsed:false
cache:"no-cache"
credentials:"include"
destination:"unknown"
headers:Headers {}
integrity:""
keepalive:false
method:"GET"
mode:"navigate"
redirect:"manual"
referrer:""
referrerPolicy:"no-referrer-when-downgrade"
signal:AbortSignal {aborted: false, onabort: null}
url:"https://my-domain.com"
__proto__:Request
回答1:
I got this working / found the fix. It was related to a redirected response security issue in the browser. From the Chromium Bugs Blog, Response.redirected and a new security restriction.
Solution: To avoid this failure, you have 2 options.
You can either change the install event handler to store the response generated from res.body:
self.oninstall = evt => { evt.waitUntil( caches.open('cache_name') .then(cache => { return fetch('/') .then(response => cache.put('/', new Response(response.body)); })); };
Or change both handlers to store the non-redirected response by setting redirect mode to ‘manual’:
self.oninstall = function (evt) { evt.waitUntil(caches.open('cache_name').then(function (cache) { return Promise.all(['/', '/index.html'].map(function (url) { return fetch(new Request(url, { redirect: 'manual' })).then(function (res) { return cache.put(url, res); }); })); })); }; self.onfetch = function (evt) { var url = new URL(evt.request.url); if (url.pathname != '/' && url.pathname != '/index.html') return; evt.respondWith(caches.match(evt.request, { cacheName: 'cache_name' })); };
来源:https://stackoverflow.com/questions/51158687/service-worker-w-offline-html-backup-page