// true production var doCache = true; // var CACHE_NAME = 'my-pwa-cache-v2'; // self.addEventListener('activate', event => { const cacheWhitelist = [CACHE_NAME]; event.waitUntil( caches.keys() .then(keyList => Promise.all(keyList.map(key => { if (!cacheWhitelist.includes(key)) { console.log('Deleting cache: ' + key) return caches.delete(key); } })) ) ); }); // 'install' , PWA self.addEventListener('install', function(event) { if (doCache) { event.waitUntil( caches.open(CACHE_NAME) .then(function(cache) { // ( ) fetch('/static/reader/manifest.json') .then(response => { response.json() }) .then(assets => { // const urlsToCache = [ '/app/', ........ '/static/core/logo.svg*', ] cache.addAll(urlsToCache) console.log('cached'); }) }) ); } }); // , - , self.addEventListener('fetch', function(event) { if (doCache) { event.respondWith( caches.match(event.request).then(function(response) { return response || fetch(event.request); }) ); } });
install
, activate
and fetch
. As soon as the user opens the site where there is a service worker, the install event will be triggered. This is the procedure for installing a service worker in the user's browser. In its handler in the urlsToCache
array urlsToCache
you can specify the pages of the site that will be cached, including statics. Then activate
is called, which clears the resources used in the previous version of the service worker script. And now that the service worker has been successfully installed, it will intercept every fetch
event and look for the requested resources in the cache before following them to the server. <!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="root"></div> <script src="/static/build/app.js"></script> <script> if ('serviceWorker' in navigator) { window.addEventListener('load', function() { navigator.serviceWorker.register('/service-worker.js').then(function(registration) { // Registration was successful console.log('ServiceWorker registration successful with scope: ', registration.scope); }, function(err) { // registration failed :( console.log('ServiceWorker registration failed: ', err); }).catch(function(err) { console.log(err) }); }); } else { console.log('service worker is not supported'); } </script> </body> </html>
navigator.serviceWorker.register('/service-worker.js')
function navigator.serviceWorker.register('/service-worker.js')
takes as its argument the URL where the service worker file is located. It does not matter how exactly the file is called, but it is important that it is located in the root of the domain. Then the service domain will be the entire domain, and it will receive fetch
events from any page. { "short_name": "", "name": "", "icons": [ { "src":"/static/core/manifest/logo-pwa-16.png", "sizes": "16x16", "type": "image/png" }, { "src":"/static/core/manifest/logo-pwa-32.png", "sizes": "32x32", "type": "image/png" }, { "src":"/static/core/manifest/logo-pwa-48.png", "sizes": "48x48", "type": "image/png" }, { "src":"/static/core/manifest/logo-pwa-72.png", "sizes": "72x72", "type": "image/png" }, { "src":"/static/core/manifest/logo-pwa-96.png", "sizes": "96x96", "type": "image/png" }, { "src":"/static/core/manifest/logo-pwa-144.png", "sizes": "144x144", "type": "image/png" }, { "src":"/static/core/manifest/logo-pwa-192.png", "sizes": "192x192", "type": "image/png" }, { "src":"/static/core/manifest/logo-pwa-512.png", "sizes": "512x512", "type": "image/png" } ], "start_url": "/app/", "background_color": "#7ACCE5", "theme_color": "#7ACCE5", "orientation": "any", "display": "standalone" }
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <title></title> <!-- Add manifest --> <link rel="manifest" href="{% static "core/manifest/manifest.json" %}"> <!-- Tell the browser it's a PWA --> </head> <body> <div id="root"></div> <script src="/static/build/app.js"></script> <script> if ('serviceWorker' in navigator) { window.addEventListener('load', function() { navigator.serviceWorker.register('/service-worker.js').then(function(registration) { // Registration was successful console.log('ServiceWorker registration successful with scope: ', registration.scope); }, function(err) { // registration failed :( console.log('ServiceWorker registration failed: ', err); }).catch(function(err) { console.log(err) }); }); } else { console.log('service worker is not supported'); } </script> </body> </html>
const isIos = () => { const userAgent = window.navigator.userAgent.toLowerCase(); return /iphone|ipad|ipod/.test( userAgent ); }; // , const isInStandaloneMode = () => ('standalone' in window.navigator) && (window.navigator.standalone); // iOS , if (isIos() && !isInStandaloneMode()) { this.setState({ isShown: true }); // React }
<script> window.addEventListener('appinstalled', (evt) => { fetch(<your_url>, { method: 'GET', credentials: 'include', }); }); </script>
start_url
specified in the manifest. Because if you specify "start_url": "/app/"
, and then the user navigates to the page, say, "/ books /", the browser’s address bar will immediately show itself and the entire user experience will break. In addition, the person will feel deceived: he thought that he was using the application, and this is a disguised browser. And even the theme_color
from the manifest, which will color the browser interface in your corporate color, will not save.Source: https://habr.com/ru/post/450504/
All Articles