self.addEventListener("fetch",function(event){
event.respondWith(
caches.match(event.request).then(function(response){// Cache hit - return responseif(response){return response;}returnfetch(event.request).then(function(response){// Check if we received a valid responseif(!response || response.status !==200|| response.type !=="basic"){return response;}// IMPORTANT: Clone the response. A response is a stream// and because we want the browser to consume the response// as well as the cache consuming the response, we need// to clone it so we have two streams.var responseToCache = response.clone();
caches.open(CACHE_NAME).then(function(cache){
cache.put(event.request, responseToCache);});return response;});}),);});
可在任何地方呼叫 self.registration.navigationPreload.enable (ex: btn click),一個適合的時機是當 service worker activate 時
enable 之後需要在 fetch 去接收 preload response
addEventListener("fetch",(event)=>{
event.respondWith((asyncfunction(){// Respond from the cache if we canconst cachedResponse =await caches.match(event.request);if(cachedResponse)return cachedResponse;// Else, use the preloaded response, if it's thereconst response =await event.preloadResponse;if(response)return response;// Else try the network.returnfetch(event.request);})(),);});
Notification.requestPermission().then(function(permission){// If the user accepts, let's create a notificationif(permission ==="granted"){// eslint-disable-next-line no-newnewNotification("See what's new!",{body:"Explore thousands of latest projects",icon:"/icons/icon_x96.png",// other options});}});
navigator.serviceWorker.register("/sw.js").then(function(registration){if(!registration.active)return registration;// sw might not active yetconst subscribeOptions ={userVisibleOnly:true,applicationServerKey:urlBase64ToUint8Array("Your VAPID Public key"),};return registration.pushManager.subscribe(subscribeOptions);});
navigator.serviceWorker.ready
navigator.serviceWorker.ready.then((registration)=>{// subscribe userconst subscribeOptions ={userVisibleOnly:true,applicationServerKey:urlBase64ToUint8Array("Your VAPID Public key"),};return registration.pushManager.subscribe(subscribeOptions);});
// setup
webpush.setVapidDetails("mailto:web-push-book@gauntface.com",
vapidKeys.publicKey,
vapidKeys.privateKey,);// send message to every subscriptionfindAllSubsInDB().then((subscriptions)=>
subscriptions.map((subscription)=>
webpush.sendNotification(
subscription,JSON.stringify({title:"Hello",}),),),);
處理 push event
event.data 可以拿到 push message,並進行轉換
self.addEventListener("push",function(event){// Returns string
event.data.text();// Parses data as JSON string and returns an Object
event.data.json();// Returns blob of data
event.data.blob();// Returns an arrayBuffer
event.data.arrayBuffer();});
使用 waitUnil 告訴 browser,直到 promise 結束, service worker 才會結束
{"//":"Visual Options","body":"<String>","icon":"<URL String>","image":"<URL String>","badge":"<URL String>","vibrate":"<Array of Integers>","sound":"<URL String>","dir":"<String of 'auto' | 'ltr' | 'rtl'>","//":"Behavioral Options","tag":"<String>","data":"<Anything>","requireInteraction":"<boolean>","renotify":"<Boolean>","silent":"<Boolean>","//":"Both visual & behavioral options","actions":"<Array of Strings>","//":"Information Option. No visual affect.","timestamp":"<Long>"}
通知行為
notificationclick event
可以定義通知被點擊時要做甚麼事
self.addEventListener("notificationclick",function(event){const clickedNotification = event.notification;
clickedNotification.close();// Do something as the result of the notification clickconst promiseChain =doSomething();
event.waitUntil(promiseChain);});
const status =await navigator.permissions.query({name:"periodic-background-sync",});if(status.state ==="granted"){// Periodic background sync can be used.}else{// Periodic background sync cannot be used.}
註冊 periodicSync
const registration =await navigator.serviceWorker.ready;if("periodicSync"in registration){try{await registration.periodicSync.register("content-sync",{// An interval of one day.minInterval:24*60*60*1000,});}catch(error){// Periodic background sync cannot be used.}}
service worker 監聽 periodicsync event
self.addEventListener("periodicsync",(event)=>{if(event.tag ==="content-sync"){// See the "Think before you sync" section for// checks you could perform before syncing.
event.waitUntil(syncContent());}// Other logic for different tags as needed.});