Is there anyway to delete my users cache? - javascript

I made a sw.js file that caches my chat website so users can open in offline mode, however, the Service Worker file caused alot of issues including not being able to see new messages and alot of website crashes so I was forced to delete it. Sadly my none of my current users can delete the cache manually! NOte that I kept the sw.js file but it's now empty so is there any code I can write to delete all of my current user caches?
I don't think this is relevant but my app uses django

To delete the cache, you can use inbuild cache API.
caches.keys().then(cacheNames => {
cacheNames.forEach(value => {
caches.delete(value);
});
})
Removing content from your sw.js file is not enough. If there is already a service worker installed and running then I would suggest you to "unRegister" that also. You can do so
programmatically using below code.
navigator.serviceWorker.getRegistrations().then(function(registrations) {
for(let registration of registrations) {
registration.unregister()
}
})
Please note you only need to run this code once in all the user's browser.

Related

The browser can't recache updated website

I've completely rewritten a website, all it's resources have been moved to other folders (changed file structure) but if I access the site from a device that has cached it, it loads the old html file and looks for the old resource paths. I've tried to solve it with meta tags, I have changed the default index.php start file to home.php in .htaccess, I tried to solve it via js, but nothing works.
After days of searching, I think that I have found the problem. The webpage was transformed to a PWA and I registered a service worker for it to cache the index.php page. I think that this service worker's cache may be my problem. How can I update it in order to recache the website? The problem is, that I can update the index.php file however I want, the browser still loads the old file.
I am sure that it can be solved somehow, but I don't have any experiences with this. Any ideas? Thanks!
var cacheName = 'prisma-pwa';
var filesToCache = [
'/',
];
/* Start the service worker and cache all of the app's content */
self.addEventListener('install', function(e) {
e.waitUntil(
caches.open(cacheName).then(function(cache) {
return cache.addAll(filesToCache);
})
);
});
/* Serve cached content when offline */
self.addEventListener('fetch', function(e) {
e.respondWith(
caches.match(e.request).then(function(response) {
return response || fetch(e.request);
})
);
});
In some few cases it's not enough to reset with F5 or even CTRL-F5. Here helps to really delete the cache in your browser.
If you use Chrome than you can disable in preferences the cache while using DevTools. This helps me sometimes. The little loss of perfomance doesn't bother me for testing.

How to really clear cache in PWA

I'm trying to debug a issue about a PWA.
I use Google Chrome to daily run the webapp and also to debug this problem (both desktop and tablet).
When I edit service-worker.js (changing the cache storage name to get out an update), the webapp doesn't reload all files fetching them from the server, but a part of them are always cached, also if in Cache Storage the name of cache (only 1, so no multiple cache) is the right.
The same thing if I use different devices (Mac and Android tablet), so I believe is not a browser problem of a specific device. The strange thing is that if I use the "Clear site data" button to empty the cache, cookies, indexeddb, etc when I reload the page, the service-worker.js install the cache (with updated name) but if I go inside the detailed view there are some files with "Time Cached" too old, before I've cleared cache and site data.
For example, in the following picture you can see different time for some files. Consider that I used "Clear site data" button at 12/6/2020 19:17:50.
The following is the part of service-worker.js with "activate" event and the const with cache name.
const name_of_cache = ['cache_v1'];
self.addEventListener('activate', event => {
console.log('Service worker activate event!');
event.waitUntil(
caches.keys().then((cacheNames) => {
return Promise.all(
cacheNames.map((cacheKeyName) => {
if(name_of_cache.indexOf(cacheKeyName) === -1) {
return caches.delete(cacheKeyName);
}
}
));
})
);
});
Where am I doing wrong? How can I solve this issue, clearing the cache and all files every time I change service-worker.js and the name of the cache?
This answer is based in this Gist: https://gist.github.com/deanhume/4b7e1f136cbee288cff9f0fc46318fbb
if ('serviceWorker' in navigator) {
caches.keys().then(function(cacheNames) {
cacheNames.forEach(function(cacheName) {
caches.delete(cacheName);
});
});
}
This will loop through each cache you have and delete it.

Vue PWA not getting new content after refresh

I'm new to Vue and created a project with the PWA Service-worker plugin. After deploying a new version of my App I get these messages in console:
After refreshing the page (F5) these messages still appear the same way and the App is still in it's old state. I tried everything to clear the cache but it still won't load the new content.
I haven't changed anything from the default config after creating my project and didn't add any code which interacts with the serviceworker. What is going wrong? Am I missing something?
As I figured out, this question is really only related to beginners in PWA, which don't know that you can (and need) to configure PWA for achieving this. If you feel addressed now (and using VueJS) remember:
To automatically download the new content, you need to configure PWA. In my case (VueJS) this is done by creating a file vue.config.js in the root directory of my project (On the same level as package.json).
Inside this file you need this:
module.exports = {
pwa: {
workboxOptions: {
skipWaiting: true
}
}
}
Which will automatically download your new content if detected.
However, the content won't be displayed to your client yet, since it needs to refresh after downloading the content. I did this by adding window.location.reload(true) to registerServiceWorker.js in my src/ directory:
updated () {
console.log('New content is available: Please refresh.')
window.location.reload(true)
},
Now, if the Service Worker detects new content, it will download it automatically and refresh the page afterwards.
I figured out a different approach to this and from what I've seen so far it works fine.
updated() {
console.log('New content is available; please refresh.');
caches.keys().then(function(names) {
for (let name of names) caches.delete(name);
});
},
What's happening here is that when the updated function gets called in the service worker it goes through and deletes all the caches. This means that your app will start up slower if there is an update but if not then it will serve the cached assets. I like this approach better because service workers can be complicated to understand and from what I've read using skipWaiting() isn't recommend unless you know what it does and the side effects it has. This also works with injectManifest mode which is how I'm currently using it.
pass registration argument then use the update() with that.
the argument uses ServiceWorkerRegistration API
updated (registration) {
console.log('New content is available; please refresh.')
registration.update()
},

how to create an offline web app using javascript

I am looking for a solution on how to create an offline compatible web app using html, JavaScript, and maybe jQuery. I looked into service workers, but they aren’t comparable with all mobile devices yet. I also looked at the manifest file thing, it worked but it didn’t update the files. So now I’m here asking for a solution. I intend this application to be a music website that can be a web app. I like music and i take it everywhere so I’m trying to find out how i can save the website files for offline use so even if I don’t have WiFi, i can listen to my saved music. btw the files I’d like to save are:
main.js
Main.css
Index.html
EDIT 1
Also, if you know how to properly use service workers, can you show an example?
For future reference:
1/ Create a service worker file in the app root folder.
Example sw.js:
let cacheName = "core" // Whatever name
// Pass all assets here
// This example use a folder named «/core» in the root folder
// It is mandatory to add an icon (Important for mobile users)
let filesToCache = [
"/",
"/index.html",
"/core/app.css",
"/core/main.js",
"/core/otherlib.js",
"/core/favicon.ico"
]
self.addEventListener("install", function(e) {
e.waitUntil(
caches.open(cacheName).then(function(cache) {
return cache.addAll(filesToCache)
})
)
})
self.addEventListener("fetch", function(e) {
e.respondWith(
caches.match(e.request).then(function(response) {
return response || fetch(e.request)
})
)
})
2/ Add an onload event anywhere in the app:
window.onload = () => {
"use strict";
if ("serviceWorker" in navigator && document.URL.split(":")[0] !== "file") {
navigator.serviceWorker.register("./sw.js");
}
}
3/ Create a manifest.json file in the app root folder.
{
"name": "APP",
"short_name": "App",
"lang": "en-US",
"start_url": "/index.html",
"display": "standalone"
}
4/ Test
Start a web server from the root folder:
php -S localhost:8090
Visit http://localhost:8090 one time.
Stop the web server with Ctrl + c.
Refresh http://localhost:8090, the page should respond.
To switch off when developing, remove the onload event, and in Firefox
visit about:debugging#workers to unregister the service.
Newest versions of Firefox are showing an application tab directly in the debugger instead. about:debugging#workers is not valid any more.
https://developer.mozilla.org/en-US/docs/Tools/Application/Service_workers
Source for more details
Manifest.json reference
If you need to save settings after the user left, you need to use cookies.
If you need some server data (and ajax requests for example), I'm afraid you can't do that offline.
For everything else (as far as I know), if you want it to work offline, you have to make the user's browser download all code it's going to use, including JQuery, Bootstrap, or any plugin code you want. You have to add them to your website sources and link them internally :
<script src="http://code.jquery.com/jquery-3-3-0-min.js"></script> <!-- Won't work offline.-->
<script src="./js/jquery-3-3-0-min.js"></script> <!-- Will work offline -->
Be careful about plugin dependencies ! For example Bootstrap 3.3.6 JS plugin needs JQuery 1.12.4
Hope it helps you !

Rewrite URL offline when using a service worker

I am making a web application with offline capabilities using a service worker generated by a Nodejs plugin called sw-precache. Everything works fine and I do have access to the html files or images offline.
But then, since you have no server-side language possible, is there a way to rewrite url client-side like an .htaccess file would do? Like showing a "404 Page not found" page when no file matches the url? I know that redirections are possible using Javascript or meta tags, but rewriting the url?
By default, sw-precache will only respond to fetch events when the URL being requested is a URL for a resource that it has cached. If someone navigations to a URL for a non-existent web page, then sw-precache won't respond to the fetch event.
That does mean that you have a chance to run your own code in an additional fetch event handler that could implement custom behavior, like returning a 404.html page when a user navigates to a non-existent page while offline. You need to jump through a couple of hoops, but here's how to do it:
// In custom-offline-import.js:
self.addEventListener('fetch', event => {
if (event.request.mode === 'navigate') {
event.respondWith(
fetch(event.request)
.catch(() => caches.match('404.html', {ignoreSearch: true}))
// {ignoreSearch: true} is needed, since sw-precache appends a search
// parameter with versioning information.
);
}
});
// In your sw-precache config:
{
// Make sure 404.html is picked up in one of the glob patterns:
staticFileGlobs: ['404.html'],
// See https://github.com/GoogleChrome/sw-precache#importscripts-arraystring
importScripts: ['custom-offline-import.js'],
}
This shouldn't interfere with anything that sw-precache is doing, as it will just be used as fallback.

Categories