Service Worker Fetching Cached Assets Failure - caching

Hello every one i'm new in service worker and i'm facing this error
The FetchEvent for "<My Local URL>" resulted in a network error response: the promise was rejected.
i don't know what it means
this is what happens when i click offline and refresh
Offline Issue From Network Tab
and here is my code
self.addEventListener('install', function(event)
{
console.log('[Service Worker] Installing Service Worker ...', event);
event.waitUntil(
caches.open('static')
.then(function(cache) {
console.log('[Service Worker] Precaching App Shell');
cache.add('/src/js/app.js')
})
)
});
self.addEventListener('activate', function(event) {
console.log('[Service Worker] Activating Service Worker ....', event);
return self.clients.claim();
});
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
if (response) {
return response;
} else {
return fetch(event.request);
}
})
);
});
Any Clue I'll Be Appreciated.

In the install event of your service worker, you add to the Cache Storage API only one item /src/js/app.js. And when you try to check how your app works offline, the first thing that is going to be fetched is HTML response for the main page and since it was not added to the cache, you are getting such results.
So you need to add to the Cache Storage all required assets for offline mode, for example, something like this:
self.addEventListener('install', function(event)
{
console.log('[Service Worker] Installing Service Worker ...', event);
event.waitUntil(
caches.open('static')
.then(function(cache) {
console.log('[Service Worker] Precaching App Shell');
cache.addAll([
'/src/js/app.js',
'/src/css/app.css',
'/src/index.html'
]);
})
)
});
...
Please check the path to the assets accordingly to your app.
Hope it will help you!

Related

How do you store a custom 404 page on the client/browser to show when there's no internet connection? [duplicate]

I have a service worker that is supposed to cache an offline.html page that is displayed if the client has no network connection. However, it sometimes believes the navigator is offline even when it is not. That is, navigator.onLine === false. This means the user may get offline.html instead of the actual content even when online, which is obviously something I'd like to avoid.
This is how I register the service worker in my main.js:
// Install service worker for offline use and caching
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js', {scope: '/'});
}
My current service-worker.js:
const OFFLINE_URL = '/mysite/offline';
const CACHE_NAME = 'mysite-static-v1';
self.addEventListener('install', (event) => {
event.waitUntil(
// Cache the offline page when installing the service worker
fetch(OFFLINE_URL, { credentials: 'include' }).then(response =>
caches.open(CACHE_NAME).then(cache => cache.put(OFFLINE_URL, response)),
),
);
});
self.addEventListener('fetch', (event) => {
const requestURL = new URL(event.request.url);
if (requestURL.origin === location.origin) {
// Load static assets from cache if network is down
if (/\.(css|js|woff|woff2|ttf|eot|svg)$/.test(requestURL.pathname)) {
event.respondWith(
caches.open(CACHE_NAME).then(cache =>
caches.match(event.request).then((result) => {
if (navigator.onLine === false) {
// We are offline so return the cached version immediately, null or not.
return result;
}
// We are online so let's run the request to make sure our content
// is up-to-date.
return fetch(event.request).then((response) => {
// Save the result to cache for later use.
cache.put(event.request, response.clone());
return response;
});
}),
),
);
return;
}
}
if (event.request.mode === 'navigate' && navigator.onLine === false) {
// Uh-oh, we navigated to a page while offline. Let's show our default page.
event.respondWith(caches.match(OFFLINE_URL));
return;
}
// Passthrough for everything else
event.respondWith(fetch(event.request));
});
What am I doing wrong?
navigator.onLine and the related events can be useful when you want to update your UI to indicate that you're offline and, for instance, only show content that exists in a cache.
But I'd avoid writing service worker logic that relies on checking navigator.onLine. Instead, attempt to make a fetch() unconditionally, and if it fails, provide a backup response. This will ensure that your web app behaves as expected regardless of whether the fetch() fails due to being offline, due to lie-fi, or due to your web server experiencing issues.
// Other fetch handler code...
if (event.request.mode === 'navigate') {
return event.respondWith(
fetch(event.request).catch(() => caches.match(OFFLINE_URL))
);
}
// Other fetch handler code...

How to use Service Worker with Yeoman webapp generator?

My project structure looks something this :
.tmp
scripts
bundle.js
bundle.map.js
app
scripts
main.js
styles
buttons.scss
grid.scss
....
main.scss
index.html
sw.js
My service worker registration :
// Register Service Worker
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
.then(reg => console.log("Registration successful"))
.catch(() => console.log("Registration failed"));
}
I wanna use Service Worker to make an offline web app, I cached the resources and implemented the code to serve them on fetch events, but although they aren't served and I keep getting this error The FetchEvent for "http://localhost:9000/" resulted in a network error response: the promise was rejected. and failed to fetch. I'm using localhost with gulp serve for dev. I think the service worker should be placed somewhere else, like .tmp maybe?? what do you think?
My sw.js file :
const staticCache = "staticCache-v1";
const staticAssets = [
//js
"browser-sync/browser-sync-client.js?v=2.24.5",
"index.html",
"scripts/bundle.js",
//css
"styles/main.scss",
//html
"index.html",
//fonts
"https://fonts.gstatic.com/s/sourcesanspro/v11/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNa7lujVj9_mf.woff2",
"https://free.currencyconverterapi.com/api/v5/currencies"
];
self.addEventListener("install", event => {
// Cache static resources
event.waitUntil(
caches.open(staticCache).then(cache => cache.addAll(staticAssets))
);
});
self.addEventListener("activate", event => {
// clean old SW
});
self.addEventListener("fetch", event => {
// try placing the sw in .tmp
console.log("fetch request :", event.request);
event.respondWith(
caches.match(event.request).then(cacheResponse => {
return cacheResponse || fetch(event.request);
})
);
});

service worker we are facing cache issue

I am a fresher for service worker. I am trying to implement static and dynamic caching.
When I add the single file to the static cache request, it is taking all the files whatever I have. Currently, all the files are running from the service worker when I started from the offline mode. Please someone help me.
This is the code I have in index.html.
self.addEventListener('install',function(event)
{
console.log('[service worker]Installing service
worker....',event);
event.waitUntil(caches.open('static')
.then(function(cache)
{
console.log('[Service Worker] Precaching App Shell');
cache.addAll([
'/',
'/signin.html',
]);
})
)
});
In Static caching some of the requests(pages) are cached(saved in Browser's local storage), it is generally done in install event of Service Worker. Whereas in Dynamic caching pages & files are cached whenever you request(fetch) for them hence, it makes use of fetch event of Service Worker.
So, in your install event when you add '/' in cache.addAll service worker adds all the files and resources needed to display '/' ie root directory.
Now, to make use of those cached files and to implement Dynamic Caching you'll need to implement something like this:
self.addEventListener('fetch', function (event) {
event.respondWith(
caches.match(event.request) // if data has been cached already
.then(function (response) {
if (response) {
return response;
} else { // else fetch from internet & cache in DYNAMIC cache
return fetch(event.request)
.then(function (res) {
return caches.open(CACHE_DYNAMIC_NAME)
.then(function (cache) {
cache.put(event.request.url, res.clone());
return res;
})
})
.catch(function (err) { //fallback mechanism
return caches.open(CACHE_STATIC_NAME)
.then(function (cache) {
if (event.request.headers.get('accept').includes('text/html')) {
return cache.match('/offline.html');
}
});
});
}
})
);
});
NOTE: To avoid over crowding your local storage you might wanna implement some strategy before actually saving the file in storage.
For more info read this to learn more about strategies.

Install Service Worker on apex.oracle.com

Can I have some help installing a Service Worker on an application stored on the server apex.oracle.com.
Im currently installing the server worker with this code running on page load:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js', {
scope : './'
}).then(function (registration) {
var serviceWorker;
if (registration.installing) {
serviceWorker = registration.installing;
printState('installing');
} else if (registration.waiting) {
serviceWorker = registration.waiting;
printState('waiting');
} else if (registration.active) {
serviceWorker = registration.active;
printState('active');
}
if (serviceWorker) {
printState(serviceWorker.state);
serviceWorker.addEventListener('statechange', function (e) {
printState(e.target.state);
});
}
}).catch (function (error) {
printState(error);
});
}
And i get the errors:
A bad HTTP response code (404) was received when fetching the script.
/pls/apex/apex//mvx/r/72250/files/static/v5/sw.js Failed to load resource: net::ERR_INVALID_RESPONSE
I have to get this application with service worker because i need it to run offline.
Any ideas?
Thanks in advance.
Edit:
Changed the lines:
navigator.serviceWorker.register('/sw.js', {
scope : './'
to
navigator.serviceWorker.register('#WORKSPACE_IMAGES#sw.js', {
scope : './#WORKSPACE_IMAGES#'
And it worked.

my browser registers the service worker and caches the urls but it doesn't work offline?

This registers and works perfectly fine online. But when the server is turned off, and when the page is refreshed, the registered serviceworker no longer shows up in the console and no caches in the cache storage.
if ("serviceWorker" in navigator){
navigator.serviceWorker.register("/sw.js").then(function(registration){
console.log("service worker reg", registration.scope)
}).catch(function(error){
console.log("Error:", error);
})
}
in sw.js
var CACHE_NAME = 'cache-v1';
var urlsToCache = [
'/index.html'
];
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open(CACHE_NAME).then(function(cache) {
return cache.addAll(urlsToCache);
})
);
//event.waitUntil(self.skipWaiting());
});
You're properly adding your file to cache, but you're missing returning your cached file on request.
Your sw.js should also have following code:
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
// Cache hit - return response
if (response) {
return response;
}
return fetch(event.request);
}
)
);
});
It's from Introduction to service workers.
Morover, you should rather cache / instead of /index.html as usually, you don't hit index.html file directly.
Your service worker doesn't show any console.log when offline, because you don't have any activate code. This article - offline cookbook is very useful to understand details.

Resources