The JavaScript code below retrieves some texts from server by using Fetch API.
fetch("index.php?user_id=1234", {
method: "GET"
}).then(function(response) {
return response.text();
}).then(function(output) {
document.getElementById("output").innerHTML = output;
});
But during network errors, it retrieves the offline page (offline.html) due to service-worker.
"use strict";
self.addEventListener("install", function() {
self.skipWaiting();
});
self.addEventListener("activate", function(activation) {
activation.waitUntil(
caches.keys().then(function(cache_names) {
for (let cache_name of cache_names) {
caches.delete(cache_name);
};
caches.open("client_cache").then(function(cache) {
return cache.add("offline.html");
});
})
);
});
self.addEventListener("fetch", function(fetching) {
fetching.respondWith(
caches.match(fetching.request).then(function(cached_response) {
return cached_response || fetch(fetching.request);
}).catch(function() {
return caches.match("offline.html");
})
);
});
I want to let the fetch request know about the network error.
And I do not want to use window.navigator. So, what can I do?
(I prefer vanilla solutions.)
You should structure your service worker's fetch event handler so that it only returns offline.html when there's a network error/cache miss and the original request is for a navigation. If the original request is not a navigation, then responding with offline.html is (as you've seen) going to result in getting back HTML for every failure.
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then((cachedResponse) => {
return cachedResponse || fetch(event.request);
}).catch((error) => {
if (event.request.mode === 'navigate') {
return caches.match('offline.html');
}
throw error;
})
);
});