極光征文 | 瀏覽器推送你該知道的秘密

前言

手機(jī)推送功能是比較常見的需求,由于墻的原因瀏覽器推送宛如雞肋,最近公司業(yè)務(wù)需要面向海外市場,所以計劃給網(wǎng)頁添加推送功能。

手機(jī) app 推送國內(nèi)有很多的推送廠商可以選擇(ex:JPush),但是瀏覽器推送由于大環(huán)境影響基本沒有類似產(chǎn)品,只能手?jǐn)](聽說 JPush 正在著手瀏覽器推送,很是期待)。聽說我司的產(chǎn)品(iOS、Android app)使用極光推送已經(jīng) 3 年了,為什么是聽說,因為我才入職兩年,手動 [捂臉]。

本文將主要介紹兩種網(wǎng)頁推送,要求網(wǎng)頁支持 HTTPS。

支持 Push Api 的瀏覽器

現(xiàn)在主流的現(xiàn)代瀏覽器都支持 Web Push API ,web push 允許瀏覽器打開的時候接收到推送(就算頁面被關(guān)閉也能接受)。

Push APi 要求網(wǎng)頁支持 HTTPS,因為 Push API 使用 Service Work 只能在 HTTPS 網(wǎng)站上使用,但是如果測試的話可以直接使用 localhost 也是允許的。

Push APi 推送的全流程如下圖所示:

image.png

瀏覽器通過如下代碼完成:


// https://example.com/webapp.js

navigator.serviceWorker.register('serviceworker.js').then(

  function(serviceWorkerRegistration) {

    serviceWorkerRegistration.pushManager.subscribe().then(

      function(pushSubscription) {

        console.log(pushSubscription.endpoint);

        console.log(pushSubscription.getKey('p256dh'));

        console.log(pushSubscription.getKey('auth'));

        // The push subscription details needed by the application

        // server are now available, and can be sent to it using,

        // for example, an XMLHttpRequest.

      }, function(error) {

        // During development it often helps to log errors to the

        // console. In a production environment it might make sense to

        // also report information about errors back to the

        // application server.

        console.log(error);

      }

    );

  });

我們需要注冊一個 ServiceWork,成功注冊后會得到一個 serviceWorkerRegistration,可以使用 serviceWorkerRegistration.pushManager.subscribe 這個方法來訂閱推送成功訂閱后返回 pushSubscription 用于標(biāo)識當(dāng)前當(dāng)前的網(wǎng)頁用戶,需要傳到自己的應(yīng)用服務(wù)中用于推送。注意現(xiàn)在是能收到推送,但是不發(fā)觸發(fā)通知,我們可以在 servicework.js 文件中添加 通知邏輯:


self.addEventListener('push', function(event) {

  console.log('[Service Worker] Push Received.');

  console.log(`[Service Worker] Push had this data: "${event.data.text()}"`);

  const title = 'Push Codelab';

  const options = {

    body: 'Yay it works.',

    icon: 'images/icon.png',

    badge: 'images/badge.png'

  };

  event.waitUntil(self.registration.showNotification(title, options));

});

服務(wù)端等到 pushSubscription 后可以通過里面的參數(shù) auth 和 p256dh 給 endpoint 發(fā)送推送請求。

到此支持 Push Api 瀏覽推送就到此結(jié)束。

Safari 的 APNs 推送

Safari 的沒有支持 Push Api 功能,但 OS X v10.9 之后可以使用 APNs 服務(wù)來支持推送功能,且功能更強(qiáng)大,允許 Safari 在關(guān)閉的情況下接受推送通知。

image.png

safari apns 要求網(wǎng)頁支持 HTTPS,不然無法請求推送,本地測試的話可以使用自建證書來測試。

Safari 推送和手機(jī)應(yīng)用推送都走的 APNS 通道,由于公司的手機(jī) APP 已經(jīng)支持了推送,后臺使用 token 做驗證,所以后臺基本不需要修改推送邏輯,非常的簡單。

注冊 Website Push IDs

首先需要在 Certificates, Identifiers & Profiles

中注冊 Website Push IDs

Register as a push provider with Apple

構(gòu)建 Push Package

當(dāng) Safari 請求推送權(quán)限的時候,Safari 會向自己的服務(wù)器請求 Push Package,如果請求失敗會返回錯誤,所以我們需要先創(chuàng)建這個 Push Package。

Push Package 最終要包含如下文件


BayAirlines.pushpackage/

    icon.iconset/

        icon_16x16.png

        icon_16x16@2x.png

        icon_32x32.png

        icon_32x32@2x.png

        icon_128x128.png

        icon_128x128@2x.png

    manifest.json

    signature

    website.json

icon.iconset/ 里面包含了推送所需的 icon。

website.json 主要包含網(wǎng)頁信息。

Manifest.json 會記錄所有的文件的 hash 值。大概長這樣


{

    "website.json": {

        "hashType": "sha512",

        "hashValue": "4309a0cf6ee37909423fb4f5f762eb530d4a7cfe9e1d30b9c85b602afb9296a508f5df00c6f63439e4dcc4484aae4cd77d1f632678ece0ef1b62ca6c9cbdebb3"

    },

    "icon.iconset/icon_16x16.png": {

        "hashType": "sha512",

        "hashValue": "8bb462e25ca79cca241355f5ae97ffab352acf7d2a0390f6547f1d0a55ade59e01e725bea70778ad2822b1ec137a8c0547197727ae2e9fed620b0d3ddea6803b"

    },

    ...

}

幸運的是 Apple 提供了一個工具讓我們很方便的生成 website.json 和 signature 這兩個文件, 我們只需要準(zhǔn)備好 icon.iconset/ 和 website.json 即可。createPushPackage.php 我們會得到 PushPackage 文件。

此時我們還需要給自己的應(yīng)用服務(wù)添加一個 API,返回剛剛生成的 PushPackage 文件。


webServiceURL/version/pushPackages/websitePushID

請求權(quán)限

請求推送權(quán)限的流程可以整理成下圖所示:

The user controls their notification permissions
  • 調(diào)用 window.safari.pushNotification.permission("< 你的 應(yīng)用 id>") 可以獲得當(dāng)前的應(yīng)用權(quán)限,如果當(dāng)前權(quán)限為 default 則表示之前沒有請求過。可以調(diào)用

window.safari.pushNotification.requestPermission(

          'The web service URL.', //

          'The Website Push ID.',    //

          {}, // Data that you choose to send to your server to help you identify the user.

          function () { } // 請求結(jié)果回調(diào)

      );

注意調(diào)用 requestPermission 時,safari 回去獲取 push package 這個文件,如果之前的不步驟沒有完成這里會失敗。如果成功則會彈框提醒用戶是否要運行當(dāng)前網(wǎng)站接收推送通知。

用戶同意后可以通過 window.safari.pushNotification.permission("< 你的 應(yīng)用 id>") 方法獲得 permission object,permission. deviceToken 需要傳到自己服務(wù)器用于給 APNS 發(fā)送推送請求。到此 safari 推送已經(jīng)完成。

Safari 推送和 iOS app 推送都是走的 APNS 服務(wù),由于之前應(yīng)用(react native 應(yīng)用)已經(jīng)集成了推送功能使用 jpush-react-native 這個插件,而且使用 token 的驗證方式,所有服務(wù)端那邊需要修改的東西比較少,只需要修改web 應(yīng)用的 keyId 即可。

done!

PS:為了極光征文大賽才注冊的簡書,平常文章都是放 GitHub 的,希望下次活動可以支持 Github 上的文章。

「本文為極光征文參賽文章」

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容