如果您向一群開發人員詢問網頁缺少哪些行動裝置功能,推播通知一定會是首要考量。
使用者可以選擇訂閱喜愛的網站發布的最新消息,您也可以透過推播通知,以吸引人的自訂內容有效地與他們互動。
自 Chrome 42 版起,開發人員可以使用 Push API 和 Notification API。
Chrome 中的 Push API 仰賴幾項不同的技術,包括網頁應用程式資訊清單和服務工作者。在本文中,我們將探討這些技術,但只會說明啟用推播訊息所需的最低要求。如要進一步瞭解資訊清單的其他功能和服務工作程的離線功能,請查看上述連結。
我們也會討論日後 Chrome 版本將新增至 API 的內容,最後會提供常見問題。
實作 Chrome 推送訊息
本節將說明您必須完成的每個步驟,以便在網路應用程式中支援推播訊息。
註冊 Service Worker
您必須使用服務工作站,才能為網路實作推送訊息。這是因為在收到推播訊息時,瀏覽器可以啟動服務工作者,在未開啟網頁的情況下在背景執行,並調度事件,讓您決定如何處理該推播訊息。
以下是如何在網路應用程式中註冊服務工作者的範例。註冊成功後,我們會呼叫 initialiseState(),我們稍後會介紹這個方法。
var isPushEnabled = false;
…
window.addEventListener('load', function() {
var pushButton = document.querySelector('.js-push-button');
pushButton.addEventListener('click', function() {
if (isPushEnabled) {
unsubscribe();
} else {
subscribe();
}
});
// Check that service workers are supported, if so, progressively
// enhance and add push messaging support, otherwise continue without it.
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js')
.then(initialiseState);
} else {
console.warn('Service workers aren\'t supported in this browser.');
}
});
按鈕點擊處理程序會讓使用者訂閱或取消訂閱推播訊息。isPushEnabled 是全域變數,只會追蹤目前是否訂閱推播訊息。這些會在程式碼片段中參照。
接著,我們會檢查是否支援服務工作站,然後註冊包含處理推播訊息邏輯的 service-worker.js
檔案。這裡我們只是告訴瀏覽器,這個 JavaScript 檔案是網站的服務工作者。
設定初始狀態
註冊服務工作者後,我們需要設定 UI 狀態。
使用者會期待簡單的使用者介面,可用來啟用或停用網站的推播訊息,並且會期待該介面能隨時更新任何變更。換句話說,如果使用者為您的網站啟用推播訊息,離開網站後一週後再回來,使用者介面應會醒目顯示已啟用推播訊息。
您可以參閱這份文件中的使用者體驗指南,本文將著重於技術層面。
您可能會認為只有兩種狀態需要處理,即啟用或停用。不過,您也需要考量通知的其他狀態。
啟用按鈕前,我們需要檢查多個 API,如果所有 API 都支援,我們就可以啟用 UI,並設定初始狀態,指出是否已訂閱推播訊息。
由於大多數的檢查會導致 UI 停用,因此您應將初始狀態設為停用。這樣一來,如果網頁的 JavaScript 發生問題 (例如無法下載 JS 檔案或使用者停用 JavaScript),就不會造成任何混淆。
<button class="js-push-button" disabled>
Enable Push Messages
</button>
有了這個初始狀態,我們就可以在 initialiseState()
方法中執行上述檢查,也就是在服務工作者註冊後。
// Once the service worker is registered set the initial state
function initialiseState() {
// Are Notifications supported in the service worker?
if (!('showNotification' in ServiceWorkerRegistration.prototype)) {
console.warn('Notifications aren\'t supported.');
return;
}
// Check the current Notification permission.
// If its denied, it's a permanent block until the
// user changes the permission
if (Notification.permission === 'denied') {
console.warn('The user has blocked notifications.');
return;
}
// Check if push messaging is supported
if (!('PushManager' in window)) {
console.warn('Push messaging isn\'t supported.');
return;
}
// We need the service worker registration to check for a subscription
navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
// Do we already have a push message subscription?
serviceWorkerRegistration.pushManager.getSubscription()
.then(function(subscription) {
// Enable any UI which subscribes / unsubscribes from
// push messages.
var pushButton = document.querySelector('.js-push-button');
pushButton.disabled = false;
if (!subscription) {
// We aren't subscribed to push, so set UI
// to allow the user to enable push
return;
}
// Keep your server in sync with the latest subscriptionId
sendSubscriptionToServer(subscription);
// Set your UI to show they have subscribed for
// push messages
pushButton.textContent = 'Disable Push Messages';
isPushEnabled = true;
})
.catch(function(err) {
console.warn('Error during getSubscription()', err);
});
});
}
以下簡要說明這些步驟:
- 我們會檢查
showNotification
是否可在 ServiceWorkerRegistration 原型中使用。否則,我們就無法在收到推播訊息時顯示服務工作者的通知。 - 我們會檢查目前的
Notification.permission
,確保其不是"denied"
。如果權限遭到拒絕,您就無法顯示通知,除非使用者在瀏覽器中手動變更權限。 - 如要確認是否支援推播訊息,我們會檢查
PushManager
是否可在視窗物件中使用。 - 最後,我們使用
pushManager.getSubscription()
檢查是否已訂閱。如果是,我們會將訂閱詳細資料傳送至伺服器,確保我們擁有正確的資訊,並設定 UI 指出是否已啟用推播訊息。我們會在本文稍後的部分,說明訂閱物件中包含哪些詳細資料。
我們會等待 navigator.serviceWorker.ready
解析完成,再檢查訂閱項目並啟用推送按鈕,因為只有在服務 worker 處於活動狀態時,您才能實際訂閱推送訊息。
接下來要處理使用者想要啟用推播訊息的情況,但在進行這項操作之前,我們需要設定 Google 開發人員控制台專案,並在資訊清單中新增一些參數,以便使用 Firebase 雲端通訊 (FCM) (舊稱 Google 雲端通訊 (GCM))。
在 Firebase 開發人員控制台中建立專案
Chrome 會使用 FCM 處理推播訊息的傳送和遞送作業;不過,如要使用 FCM API,您必須在 Firebase 開發人員控制台上設定專案。
以下步驟適用於使用 FCM 的 Chrome、Android 版 Opera 和 Samsung Browser。我們會在文章稍後的部分討論這項功能在其他瀏覽器中的運作方式。
建立新的 Firebase 開發人員專案
首先,請在 https://console.firebase.google.com/ 中按一下「Create New Project」(建立新專案),建立新專案。
新增專案名稱並建立專案後,系統會將您帶往專案資訊主頁:
在這個資訊主頁中,按一下左上角專案名稱旁的齒輪圖示,然後點選「專案設定」。
在設定頁面中,按一下「Cloud Messaging」分頁標籤。
這個頁面包含用於推播訊息的 API 金鑰 (稍後會用到),以及我們需要在下一節的網頁應用程式資訊清單中放入的寄件者 ID。
新增網頁應用程式資訊清單
針對推播,我們需要新增含有 gcm_sender_id 欄位的資訊清單檔案,才能成功訂閱推播。只有 Chrome、Android 版 Opera 和 Samsung Browser 需要這個參數,才能使用 FCM / GCM。
這些瀏覽器會在使用者裝置訂閱 FCM 時使用 gcm_sender_id。這表示 FCM 可以識別使用者的裝置,並確保您的寄件者 ID 與對應的 API 金鑰相符,以及使用者已授權伺服器傳送推播訊息。
以下是超簡單的資訊清單檔案:
{
"name": "Push Demo",
"short_name": "Push Demo",
"icons": [{
"src": "images/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
}],
"start_url": "/index.html?homescreen=1",
"display": "standalone",
"gcm_sender_id": "<Your Sender ID Here>"
}
您必須將 gcm_sender_id 值設為 Firebase 專案中的寄件者 ID。
將資訊清單檔案儲存至專案後 (建議使用 manifest.json 做為檔案名稱),請在頁面標頭中使用下列標記,從 HTML 參照該檔案。
<link rel="manifest" href="/manifest.json">
如果您未加入含有這些參數的網頁資訊清單,嘗試讓使用者訂閱推播訊息時,系統會傳回例外狀況,並顯示錯誤 "Registration failed - no sender id provided"
或 "Registration failed -
permission denied"
。
訂閱推送訊息
您已設定資訊清單,現在可以返回網站的 JavaScript。
如要訂閱,您必須在 PushManager 物件上呼叫 subscribe() 方法,而該物件可透過 ServiceWorkerRegistration 存取。
這會要求使用者授予您發送推播通知的來源權限。如未授予這項權限,您將無法成功訂閱。
如果 subscribe() 方法傳回的 promise 解析,您將獲得 PushSubscription 物件,其中包含 端點。
您需要在日後傳送推播訊息,因此應為每位使用者儲存端點。
以下程式碼會讓使用者訂閱推播訊息:
function subscribe() {
// Disable the button so it can't be changed while
// we process the permission request
var pushButton = document.querySelector('.js-push-button');
pushButton.disabled = true;
navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
serviceWorkerRegistration.pushManager.subscribe()
.then(function(subscription) {
// The subscription was successful
isPushEnabled = true;
pushButton.textContent = 'Disable Push Messages';
pushButton.disabled = false;
// TODO: Send the subscription.endpoint to your server
// and save it to send a push message at a later date
return sendSubscriptionToServer(subscription);
})
.catch(function(e) {
if (Notification.permission === 'denied') {
// The user denied the notification permission which
// means we failed to subscribe and the user will need
// to manually change the notification permission to
// subscribe to push messages
console.warn('Permission for Notifications was denied');
pushButton.disabled = true;
} else {
// A problem occurred with the subscription; common reasons
// include network errors, and lacking gcm_sender_id and/or
// gcm_user_visible_only in the manifest.
console.error('Unable to subscribe to push.', e);
pushButton.disabled = false;
pushButton.textContent = 'Enable Push Messages';
}
});
});
}
此時,您的網路應用程式已可接收推播訊息,但在我們將推播事件事件監聽器新增至服務 worker 檔案之前,不會有任何動作。
Service Worker 推送事件監聽器
收到推播訊息時 (我們會在下一節說明如何實際傳送推播訊息),服務工作者會發送推播事件,此時您需要顯示通知。
self.addEventListener('push', function(event) {
console.log('Received a push message', event);
var title = 'Yay a message.';
var body = 'We have received a push message.';
var icon = '/images/icon-192x192.png';
var tag = 'simple-push-demo-notification-tag';
event.waitUntil(
self.registration.showNotification(title, {
body: body,
icon: icon,
tag: tag
})
);
});
這段程式碼會註冊推播事件監聽器,並顯示含有預先定義標題、內文、圖示和通知標記的通知。這個範例中值得注意的細微之處是 event.waitUntil()
方法。這個方法會接收promise,並延長事件處理常式的生命週期 (或可視為讓服務 worker 保持運作),直到 promise 完成為止;在這種情況下,傳遞至 event.waitUntil
的 promise 是從 showNotification()
傳回的 Promise。
通知標記可做為不重複通知的識別碼。如果我們傳送兩則推播訊息至同一個端點,且兩者之間有短暫延遲,並顯示同一個標記的通知,瀏覽器會顯示第一則通知,並在收到推播訊息時將其替換為第二則通知。
如果您想一次顯示多則通知,請使用其他代碼,或不使用任何代碼。我們將在本文稍後的部分,查看顯示通知的完整範例。我們先簡化一下,看看傳送推播訊息時是否會顯示這則通知。
傳送推送訊息
我們已訂閱推播訊息,服務工作者也已準備好顯示通知,因此是時候透過 FCM 傳送推播訊息了。
這項設定僅適用於使用 FCM 的瀏覽器。
將 PushSubscription.endpoint
變數傳送至伺服器時,FCM 的端點會是特殊的。網址結尾有參數 registration_id
。
端點範例如下:
https://fcm.googleapis.com/fcm/send/APA91bHPffi8zclbIBDcToXN_LEpT6iA87pgR-J-MuuVVycM0SmptG-rXdCPKTM5pvKiHk2Ts-ukL1KV8exGOnurOAKdbvH9jcvg8h2gSi-zZJyToiiydjAJW6Fa9mE3_7vsNIgzF28KGspVmLUpMgYLBd1rxaVh-L4NDzD7HyTkhFOfwWiyVdKh__rEt15W9n2o6cZ8nxrP
FCM 網址如下:
https://fcm.googleapis.com/fcm/send
registration_id
會是:
APA91bHPffi8zclbIBDcToXN_LEpT6iA87pgR-J-MuuVVycM0SmptG-rXdCPKTM5pvKiHk2Ts-ukL1KV8exGOnurOAKdbvH9jcvg8h2gSi-zZJyToiiydjAJW6Fa9mE3_7vsNIgzF28KGspVmLUpMgYLBd1rxaVh-L4NDzD7HyTkhFOfwWiyVdKh__rEt15W9n2o6cZ8nxrP
這項功能僅適用於使用 FCM 的瀏覽器。在一般瀏覽器中,您只需取得端點,並以標準方式呼叫該端點,無論網址為何,都會正常運作。
這表示您需要在伺服器上檢查端點是否適用於 FCM,如果是,請擷取 registration_id。如要在 Python 中執行此操作,可以執行以下操作:
if endpoint.startswith('https://fcm.googleapis.com/fcm/send'):
endpointParts = endpoint.split('/')
registrationId = endpointParts[len(endpointParts) - 1]
endpoint = 'https://fcm.googleapis.com/fcm/send'
取得註冊 ID 後,您就可以呼叫 FCM API。如要查看 FCM API 的參考文件,請按這裡。
呼叫 FCM 時,請注意以下幾點:
- 呼叫 API 時,必須設定值為
key=<YOUR_API_KEY>
的 Authorization 標頭,其中<YOUR_API_KEY>
是 Firebase 專案的 API 金鑰。- FCM 會使用 API 金鑰尋找適當的寄件者 ID,確保使用者已授予專案權限,並最終確保伺服器的 IP 位址已列入該專案的許可清單。
- 視您傳送的資料是 JSON 還是表單資料而定,使用
application/json
或application/x-www-form-urlencoded;charset=UTF-8
的適當Content-Type
標頭。 registration_ids
陣列 - 這些是您從使用者端點擷取的註冊 ID。
請查看說明文件,瞭解如何從伺服器傳送推播訊息,但如要快速檢查服務工作程,您可以使用 cURL 將推播訊息傳送至瀏覽器。
將這個 cURL 指令中的 <YOUR_API_KEY>
和 <YOUR_REGISTRATION_ID>
換成您自己的值,然後透過終端機執行。
您應該會看到以下通知:
curl --header "Authorization: key=<YOUR_API_KEY>" --header
"Content-Type: application/json" https://fcm.googleapis.com/fcm/send -d
"{\"registration_ids\":[\"<YOUR_REGISTRATION_ID>\"]}"
開發後端邏輯時,請記住授權標頭和 POST 主體的格式是專屬於 FCM 端點,因此請偵測端點是否為 FCM,並根據條件新增標頭和格式化 POST 主體。對於其他瀏覽器 (希望未來 Chrome 也能支援),您需要導入Web Push 通訊協定。
目前在 Chrome 中實作 Push API 的缺點是,您無法透過推送訊息傳送任何資料。沒有。這是因為在日後的實作中,酬載資料必須先在伺服器上加密,才能傳送至推播訊息端點。如此一來,無論端點使用哪個推播供應商,都無法輕易查看推播訊息的內容。這也能防範其他安全漏洞,例如 HTTPS 憑證驗證不佳,以及伺服器和推播供應商之間的中間人攻擊。不過,這項加密功能尚未支援,因此您必須執行擷取作業,才能取得填入通知所需的資訊。
更完整的推播事件範例
我們目前看到的通知相當基本,而且就樣本而言,無法涵蓋實際使用情境。
實際上,大多數使用者會先從伺服器取得一些資訊,再顯示通知。這可能會是填入通知標題和訊息的資料,或是進一步快取某些網頁或資料,以便在使用者點選通知時,即使網路在該時間點無法使用,瀏覽器也能立即提供所有內容。
在以下程式碼中,我們會從 API 擷取部分資料,將回應轉換為物件,並使用該物件填入通知。
self.addEventListener('push', function(event) {
// Since there is no payload data with the first version
// of push messages, we'll grab some data from
// an API and use it to populate a notification
event.waitUntil(
fetch(SOME_API_ENDPOINT).then(function(response) {
if (response.status !== 200) {
// Either show a message to the user explaining the error
// or enter a generic message and handle the
// onnotificationclick event to direct the user to a web page
console.log('Looks like there was a problem. Status Code: ' + response.status);
throw new Error();
}
// Examine the text in the response
return response.json().then(function(data) {
if (data.error || !data.notification) {
console.error('The API returned an error.', data.error);
throw new Error();
}
var title = data.notification.title;
var message = data.notification.message;
var icon = data.notification.icon;
var notificationTag = data.notification.tag;
return self.registration.showNotification(title, {
body: message,
icon: icon,
tag: notificationTag
});
});
}).catch(function(err) {
console.error('Unable to retrieve data', err);
var title = 'An error occurred';
var message = 'We were unable to get the information for this push message';
var icon = URL_TO_DEFAULT_ICON;
var notificationTag = 'notification-error';
return self.registration.showNotification(title, {
body: message,
icon: icon,
tag: notificationTag
});
})
);
});
值得一提的是,event.waitUntil()
會採用承諾,導致 showNotification()
傳回承諾,也就是說,非同步 fetch()
呼叫完成後,事件監聽器才會退出,並顯示通知。
您會發現,即使發生錯誤,我們也會顯示通知。這是因為如果我們不這麼做,Chrome 就會顯示自己的一般通知。
使用者點按通知時開啟網址
使用者點選通知時,服務工作者會調度 notificationclick
事件。您可以在處理程序中採取適當的動作,例如將焦點放在分頁上,或開啟含有特定網址的視窗:
self.addEventListener('notificationclick', function(event) {
console.log('On notification click: ', event.notification.tag);
// Android doesn't close the notification when you click on it
// See: http://crbug.com/463146
event.notification.close();
// This looks to see if the current is already open and
// focuses if it is
event.waitUntil(
clients.matchAll({
type: "window"
})
.then(function(clientList) {
for (var i = 0; i < clientList.length; i++) {
var client = clientList[i];
if (client.url == '/' && 'focus' in client)
return client.focus();
}
if (clients.openWindow) {
return clients.openWindow('/');
}
})
);
});
這個範例會開啟瀏覽器,並將焦點放在網站來源的根目錄上,如果有現有的同源分頁,就會將焦點放在該分頁上,否則會開啟新的分頁。
這篇文章將介紹您可以使用 Notification API 執行的部分操作。
取消訂閱使用者的裝置
您已訂閱使用者的裝置,且他們正在接收推播訊息,但您如何取消訂閱?
要取消使用者裝置的訂閱,主要需要在 PushSubscription 物件上呼叫 unsubscribe()
方法,並從伺服器中移除端點 (這樣就不會傳送您知道不會收到的推播訊息)。以下程式碼會執行上述操作:
function unsubscribe() {
var pushButton = document.querySelector('.js-push-button');
pushButton.disabled = true;
navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
// To unsubscribe from push messaging, you need get the
// subscription object, which you can call unsubscribe() on.
serviceWorkerRegistration.pushManager.getSubscription().then(
function(pushSubscription) {
// Check we have a subscription to unsubscribe
if (!pushSubscription) {
// No subscription object, so set the state
// to allow the user to subscribe to push
isPushEnabled = false;
pushButton.disabled = false;
pushButton.textContent = 'Enable Push Messages';
return;
}
var subscriptionId = pushSubscription.subscriptionId;
// TODO: Make a request to your server to remove
// the subscriptionId from your data store so you
// don't attempt to send them push messages anymore
// We have a subscription, so call unsubscribe on it
pushSubscription.unsubscribe().then(function(successful) {
pushButton.disabled = false;
pushButton.textContent = 'Enable Push Messages';
isPushEnabled = false;
}).catch(function(e) {
// We failed to unsubscribe, this can lead to
// an unusual state, so may be best to remove
// the users data from your data store and
// inform the user that you have done so
console.log('Unsubscription error: ', e);
pushButton.disabled = false;
pushButton.textContent = 'Enable Push Messages';
});
}).catch(function(e) {
console.error('Error thrown while unsubscribing from push messaging.', e);
});
});
}
讓訂閱項目保持在最新狀態
FCM 和伺服器之間的訂閱項目可能會不同步。請確認您的伺服器會剖析 FCM API 傳送 POST 要求的回應主體,並尋找 error:NotRegistered
和 canonical_id
結果,詳情請參閱 FCM 說明文件。
訂閱項目也可能會在服務工作者和伺服器之間不同步。舉例來說,在成功訂閱/取消訂閱後,不穩定的網路連線可能會導致您無法更新伺服器;或者,使用者可能會撤銷通知權限,進而觸發自動取消訂閱。如要處理這類情況,請定期 (例如在網頁載入時) 檢查 serviceWorkerRegistration.pushManager.getSubscription()
的結果,並將結果與伺服器同步。如果您不再訂閱,且 Notification.permission == 'granted',您可能也想自動重新訂閱。
在 sendSubscriptionToServer()
中,您必須考量如何在更新 endpoint
時處理失敗的網路要求。其中一個解決方案是追蹤 Cookie 中的 endpoint
狀態,以判斷伺服器是否需要最新詳細資料。
上述所有步驟完成後,Chrome 46 就會在網頁上完整實作推播訊息功能。我們仍提供一些可讓您更輕鬆操作的功能 (例如用於觸發推播訊息的標準 API),但您現在就能開始在網路應用程式中建構推播訊息。
如何對網頁應用程式偵錯
在實作推播訊息時,錯誤會出現在以下任一位置:網頁或服務工作者。
您可以使用DevTools偵錯網頁中的錯誤。如要對服務工作程式問題進行偵錯,您有兩種方法:
- 前往 chrome://inspect > Service workers。除了目前執行中的服務工作者,這個檢視畫面不會提供太多資訊。
- 前往 chrome://serviceworker-internals,您可以在這裡查看服務工作者的狀態,並查看錯誤 (如有)。這個頁面是暫時性的,等到開發人員工具提供類似的功能集後,就會移除。
對於服務工作程式新手,我能提供的最佳提示之一,就是使用名為「Open DevTools window and pause JavaScript execution on service worker startup for debugging」的核取方塊。這個核取方塊會在服務工作者開始時加入中斷點,並暫停執行,讓您可以繼續執行或逐步執行服務工作者指令碼,並查看是否發生任何問題。
如果 FCM 和服務工作者的推送事件之間似乎有問題,您就無法查看 Chrome 是否收到任何內容,因此無法對問題進行偵錯。您需要確保的是,當伺服器發出 API 呼叫時,FCM 的回應是否成功。如下所示:
{"multicast_id":1234567890,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1234567890"}]}
請留意 "success": 1
回應。如果您看到失敗訊息,表示 FCM 註冊 ID 有問題,且推送訊息並未傳送至 Chrome。
在 Android 版 Chrome 上對 Service Worker 進行除錯
目前在 Android 版 Chrome 上偵錯服務工作程並不明顯。您必須前往 chrome://inspect,找出裝置,然後尋找名稱為「Worker pid:....」的清單項目,其中包含服務 worker 的網址。
推播通知的使用者體驗
Chrome 團隊已彙整一份文件,其中包含推播通知使用者體驗的最佳做法,以及使用推播通知時的某些極端情況。
Chrome 和開放網路上的推播訊息未來發展
本節將詳細說明此實作項目的部分 Chrome 專屬部分,以及與其他瀏覽器實作項目的差異。
網路推播通訊協定和端點
Push API 標準的優點在於,您可以使用端點,將其傳遞至伺服器,並透過實作 Web Push Protocol 傳送推播訊息。
Web Push 通訊協定是推播供應商可實作的全新標準,可讓開發人員不必擔心推播供應商為何人。這項通訊協定的概念是避免使用者需要註冊 API 金鑰,以及傳送格式特別的資料 (如使用 FCM 時)。
Chrome 是第一個實作 Push API 的瀏覽器,而 FCM 不支援 Web Push 通訊協定,因此 Chrome 需要 gcm_sender_id
,您也需要使用 FCM 的 restful API。
Chrome 的最終目標是使用 Chrome 和 FCM 搭配網頁推播通訊協定。
在此之前,您需要偵測端點「https://fcm.googleapis.com/fcm/send」,並與其他端點分開處理,也就是以特定方式格式化酬載資料並新增授權金鑰。
How to Implement the Web Push Protocol?
Firefox Nightly 目前正在開發推播功能,很可能會是第一個導入 Web Push 通訊協定的瀏覽器。
常見問題
規格在哪裡?
https://slightlyoff.github.io/ServiceWorker/spec/service_worker/ https://w3c.github.io/push-api/ https://notifications.spec.whatwg.org/
如果我的網站有不同來源,或是同時有網站和原生網站,我可以避免收到重複通知嗎?
目前沒有解決方法,但你可以在 Chromium 上追蹤進度。
理想情況下,您應為使用者的裝置提供某種 ID,然後在伺服器端比對原生應用程式和網頁應用程式訂閱 ID,並決定要將推播訊息傳送至哪一個。您可以透過螢幕大小、裝置型號,在網頁版應用程式和原生應用程式之間共用產生的金鑰,但每種方法都有優缺點。
為什麼需要 gcm_sender_id?
這項設定是必要的,才能讓 Chrome、Android 版 Opera 和 Samsung 瀏覽器使用 Firebase 雲端通訊 (FCM) API。目標是在標準定案且 FCM 可支援時,使用 Web Push 通訊協定。
為什麼不使用 Web Sockets 或伺服器傳送事件 (EventSource)?
使用推播訊息的好處是,即使網頁關閉,服務工作者也會喚醒並顯示通知。關閉網頁或瀏覽器時,Web Sockets 和 EventSource 的連線會關閉。
如果我不需要背景事件提交功能,該怎麼辦?
如果您不需要背景提交,Web Sockets 就是不錯的選擇。
何時可以使用推播功能,而不顯示通知 (即靜默背景推播)?
目前尚未決定何時推出這項功能,但我們有意圖實作背景同步功能,雖然尚未決定或規範,但我們已討論過如何透過背景同步功能啟用無聲推播。
為什麼需要使用 HTTPS?如何在開發期間解決這個問題?
Service Worker 需要安全的來源,以確保 Service Worker 指令碼來自預期的來源,且並非來自中間人攻擊。目前這表示在實際網站上使用 HTTPS,不過在開發期間,本機會正常運作。
瀏覽器支援功能的運作方式為何?
Chrome 穩定版支援這項功能,Mozilla 也正在 Firefox Nightly 中推動這項功能。詳情請參閱「導入推送 API」錯誤,您也可以在這裡追蹤通知導入作業。
我可以在一段時間後移除通知嗎?
目前無法做到,但我們預計會新增支援功能,讓您取得目前顯示的通知清單。如果您有用途,需要在通知顯示建立後設定到期時間,我們很樂意瞭解那是什麼,因此請新增留言,我們會將其傳回給 Chrome 團隊。
如果您只想在特定時間後停止向使用者傳送推播通知,且不關心通知會顯示多久,可以使用 FCM 的有效時間 (ttl) 參數,請參閱這篇文章瞭解詳情。
Chrome 中的推播訊息有哪些限制?
這篇文章會說明幾項限制:
- Chrome 使用 CCM 做為推播服務,因此會產生一些專屬要求。我們正在合作,看看日後是否可以解除其中一些限制。
- 您必須在收到推播訊息時顯示通知。
- 電腦版 Chrome 有個警告,如果 Chrome 未執行,就不會收到推播訊息。這與 ChromeOS 和 Android 不同,後者會一律接收推播訊息。
我們不應該使用 Permissions API 嗎?
Permission API 已在 Chrome 中實作,但不一定適用於所有瀏覽器。詳情請參閱這篇文章。
為什麼 Chrome 在點選通知時不會開啟先前的分頁?
這項問題只會影響目前未由 Service Worker 控管的網頁。您可以參閱這個網頁來瞭解詳情。
如果通知在使用者裝置收到推播時已過期,該怎麼辦?
收到推播訊息時,您必須一律顯示通知。如果您想傳送通知,但該通知只在特定時間內有效,您可以在 CCM 上使用「time_to_live」參數,這樣在過期時間過後,FCM 就不會傳送推播訊息。
如果我傳送 10 則推播訊息,但只想讓裝置接收其中 1 則,會發生什麼情況?
FCM 提供「collapse_key」參數,可用來告知 FCM 將任何具有相同「collapse_key」的待處理訊息,替換為新訊息。