在本程式碼研究室中,您將使用 Service Worker 管理通知。 此處的操作說明假設您已熟悉 以及要求通知權限和傳送通知的基本概念。 如需複習通知內容,請參閱 開始使用通知 API 程式碼研究室。如要進一步瞭解服務工作處理程序,請參閱 Matt Gaunt 的服務工作人員簡介。
重混範例應用程式,並在新分頁中查看
系統會自動封鎖內嵌的 Glitch 應用程式通知,因此您無法在這個頁面預覽應用程式。而是可以採取以下做法:
- 按一下「Remix to Edit」即可編輯專案。
- 如要預覽網站,請按下「查看應用程式」。然後按下
全螢幕
。
Glitch 應該會在新的 Chrome 分頁中開啟。
在您學習本程式碼研究室的過程中,請變更本頁面內嵌 Glitch 中的程式碼。為執行中的應用程式重新整理新分頁,就會看到變更。
熟悉範例應用程式並編寫程式碼
首先在 Chrome 新分頁中查看已上線的應用程式:
- 按下 Control+Shift+J 鍵 (或在 Mac 上為 Command+Option+J 鍵) 開啟開發人員工具。
再按一下「Console」(控制台) 分頁標籤即可。
確認已在「Levels」下拉式選單中選取「Info」選項 。
在您上線應用程式的開發人員工具控制台中,您應該會看到主控台訊息:
TODO: Implement getRegistration()
。這是來自本程式碼研究室的函式虛設常式訊息。
接著,我們來看看這個網頁上內嵌的 Glitch 中範例應用程式的程式碼。
在嵌入式 Glitch 中,查看
public/index.js
:您實作的函式會有四個虛設常式:
registerServiceWorker
、getRegistration
、unRegisterServiceWorker
和sendNotification
。requestPermission
函式會要求使用者授予傳送通知的權限。如果您已完成開始使用通知 API 程式碼研究室,你會發現這裡使用了其requestPermission
函式。唯一的差別在於現在也會在解決權限要求後更新使用者介面。updateUI
函式會重新整理應用程式的所有按鈕和訊息。initializePage
函式會在瀏覽器中執行 Service Worker 功能偵測功能,並更新應用程式使用者介面。指令碼會等到網頁載入後才會初始化。
在嵌入式 Glitch 中,開啟
public/service-worker.js
。顧名思義,您需要在應用程式中新增程式碼,將這個檔案註冊為 service Worker。
雖然此檔案尚未由應用程式使用,但包含一些範例程式碼,會在服務工作站啟用時將訊息輸出至主控台。
您要將程式碼新增至
public/service-worker.js
,以便在服務工作處理程序收到通知時處理通知。
註冊 Service Worker
在這個步驟中,您將編寫可執行
當使用者在應用程式 UI 中按一下 [註冊 Service Worker] 時。
這個程式碼會將 public/service-worker.js
註冊為 Service Worker。
在內嵌的 Glitch 編輯器中開啟
public/index.js
。 使用下列程式碼取代registerServiceWorker
函式:// Use the Service Worker API to register a service worker. async function registerServiceWorker() { await navigator.serviceWorker.register('./service-worker.js') updateUI(); }
請注意,
registerServiceWorker
會使用async function
宣告,讓處理承諾更方便。如此一來,您就可以await
Promise
的解析值。舉例來說,上述函式會等待註冊 Service Worker 的結果再更新 UI。詳情請參閱 MDN 上的await
。使用者現在可以註冊 Service Worker,因此您可以取得 Service Worker 註冊物件的參照。在
public/index.js
中,將getRegistration
函式替換為以下程式碼:// Get the current service worker registration. function getRegistration() { return navigator.serviceWorker.getRegistration(); }
上述函式使用 Service Worker API 取得目前的 Service Worker 註冊 (如果有的話)。 如此一來,取得 Service Worker 註冊的參照就更加方便。
如要完成 Service Worker 的註冊功能,請新增程式碼,取消註冊 Service Worker。使用下列程式碼取代
unRegisterServiceWorker
函式:// Unregister a service worker, then update the UI. async function unRegisterServiceWorker() { // Get a reference to the service worker registration. let registration = await getRegistration(); // Await the outcome of the unregistration attempt // so that the UI update is not superceded by a // returning Promise. await registration.unregister(); updateUI(); }
在你目前查看實際應用程式的分頁中,重新載入頁面。「Register Service Worker」和「Unregister service worker」按鈕現在應可正常運作。
傳送通知給 Service Worker
在這個步驟中,您必須編寫會在使用者點選應用程式 UI 中的「傳送通知」時執行的程式碼。這個程式碼將建立通知,檢查 Service Worker 是否已註冊,然後使用 postMessage
方法傳送通知給 Service Worker。
在內嵌的 Glitch 編輯器中,開啟 public/index.js
並
將 sendNotification
函式替換為以下程式碼:
// Create and send a test notification to the service worker.
async function sendNotification() {
// Use a random number as part of the notification data
// (so you can tell the notifications apart during testing!)
let randy = Math.floor(Math.random() * 100);
let notification = {
title: 'Test ' + randy,
options: { body: 'Test body ' + randy }
};
// Get a reference to the service worker registration.
let registration = await getRegistration();
// Check that the service worker registration exists.
if (registration) {
// Check that a service worker controller exists before
// trying to access the postMessage method.
if (navigator.serviceWorker.controller) {
navigator.serviceWorker.controller.postMessage(notification);
} else {
console.log('No service worker controller found. Try a soft reload.');
}
}
}
該程式碼的功能如下:
sendNotification
是非同步函式,因此您可以使用await
來取得註冊 Service Worker 的參照。Service Worker 的
postMessage
方法會將應用程式中的資料傳送至 Service Worker。詳情請參閱 postMessage 的 MDN 說明文件。程式碼會先檢查
navigator.serviceWorker.controller
屬性是否存在,再嘗試存取postMessage
函式。如果沒有任何使用中的 Service Worker,或強制重新整理頁面,navigator.serviceWorker.controller
將為null
(Shift+
重新載入)。詳情請參閱 MDN 的 ServiceWorker 控制器說明文件。
處理 Service Worker 中的通知
在這個步驟中,您將在 Service Worker 中編寫程式碼,以處理發布至使用者的訊息,並向使用者顯示通知。
在內嵌的 Glitch 編輯器中開啟 public/service-worker.js
。將下列程式碼新增至檔案結尾:
// Show notification when received
self.addEventListener('message', (event) => {
let notification = event.data;
self.registration.showNotification(
notification.title,
notification.options
).catch((error) => {
console.log(error);
});
});
以下為快速說明:
self
是 Service Worker 本身的參照。雖然服務工作處理程序現在可以處理顯示通知,但主要應用程式 UI 仍負責向使用者取得通知權限。如果使用者未授予權限,
showNotification
回傳的承諾使用合約會遭到拒絕。上述程式碼使用catch
區塊,避免發生未偵測到的Promise
拒絕錯誤,並以更妥善的方式處理這項錯誤。
如果遇到困難,請前往 glitch.com/edit/#!/codelab-notifications-service-worker-completed,瞭解已完成的程式碼。
請前往本系列的下一個程式碼研究室:建構推播通知伺服器。