- 原文地址:Sending Web Push Notifications from Node.js
- 原文做者:code_barbarian
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:lsvih
- 校對者:talisk
使用 service workers API 可讓你直接由 Node.js 應用向 Chrome 瀏覽器發送推送通知。web-push
npm 模組可讓你免去 PubNub 之類的中間商,直接推送消息。本文將在前端使用原生 JavaScript,在後端使用 Express 框架,經過一個「Hello, World」級別的樣例來帶你瞭解如何進行 web 推送通知。最終的效果以下圖所示。本項目的所有源碼可在 GitHub 查閱。javascript
要設置 web 推送,必須先建立 VAPID keys。VAPID keys 用於識別是誰發送了推送消息。npm 的 web-push
模組可以幫助你生成 VAPID keys,下面咱們將安裝 web-push
及其依賴,並使用 web-push generate-vapid-keys
來建立 VAPID keys。html
$ npm install express@4.16.3 web-push@3.3.0 body-parser@1.18.2 express-static@1.2.5 + express@4.16.3 + web-push@3.3.0 + body-parser@1.18.2 + express-static@1.2.5 added 62 packages in 1.42s $ $ ./node_modules/.bin/web-push generate-vapid-keys ======================================= Public Key: BOynOrGhgkj8Bfk4hsFENAQYbnqqLSigUUkCNaBsAmNuH6U9EWywR1JIdxBVQOPDbIuTaj0tVAQbczNLkC5zftw Private Key: <OMITTED> ======================================= $ 複製代碼
若是你須要支持低版本瀏覽器,那麼還要獲取 GCM API key,但在桌面版 Chrome 63 或更高版本中不須要它。前端
下面建立 index.js
文件,其中包含你的服務。你須要使用 require()
導入 web-push 模組,並配置剛纔的 VAPID keys。配置至關簡單,將 VAPID keys 存放在 PUBLIC_VAPID_KEY
與 PRIVATE_VAPID_KEY
環境變量中便可。java
const webpush = require('web-push'); const publicVapidKey = process.env.PUBLIC_VAPID_KEY; const privateVapidKey = process.env.PRIVATE_VAPID_KEY; // 此處換成你本身的郵箱 webpush.setVapidDetails('mailto:val@karpov.io', publicVapidKey, privateVapidKey); 複製代碼
下一步,爲 Express 應用添加一個名爲 /subscribe
的端點。瀏覽器中的 JavaScript 將會發送一個 body 中包含 PushSubscription
對象的 HTTP 請求。爲了用 webpush.sendNotification()
發送推送通知,你須要獲取 PushSubscription
對象。node
const app = express(); app.use(require('body-parser').json()); app.post('/subscribe', (req, res) => { const subscription = req.body; res.status(201).json({}); const payload = JSON.stringify({ title: 'test' }); console.log(subscription); webpush.sendNotification(subscription, payload).catch(error => { console.error(error.stack); }); }); 複製代碼
以上就是服務端須要作的所有配置。你能夠在 GitHub 查閱完整代碼。如今,咱們就要建立客戶端 client.js
與一個 service worker —— worker.js
了。react
首先,使用 express-static
npm 模組,對 Express 應用進行配置,爲客戶端部署靜態資源,將靜態資源部署在服務的最頂級目錄下。 須要注意的是要在處理 /subscribe
路由以後再調用這個 app.use()
,不然 Express 將不會根據你的配置處理路由,而是會去查找 subscribe.html
文件。android
app.use(require('express-static')('./')); 複製代碼
接着,建立 index.html
文件,這個文件將部署爲你的應用的入口。文件中僅有的關鍵之處就是 <script>
標籤,它將加載客戶端 JavaScript 代碼;其他部分都可有可無。ios
<html> <head> <title>Push Demo</title> <script type="application/javascript" src="/client.js"></script> </head> <body> Service Worker Demo </body> </html> 複製代碼
如今你的入口作好了。建立一個名爲 client.js
的文件。這個文件 將告知瀏覽器初始化你的 service worker 並向 /subscribe
發送 HTTP 請求。因爲支持 service workers 的瀏覽器也應該能支持 async 與 await,所以上述示例中使用了 async/await。git
// 這裏寫死的 public key 要換成你本身的。 const publicVapidKey = 'BOynOrGhgkj8Bfk4hsFENAQYbnqqLSigUUkCNaBsAmNuH6U9EWywR1JIdxBVQOPDbIuTaj0tVAQbczNLkC5zftw'; if ('serviceWorker' in navigator) { console.log('Registering service worker'); run().catch(error => console.error(error)); } async function run() { console.log('Registering service worker'); const registration = await navigator.serviceWorker. register('/worker.js', {scope: '/'}); console.log('Registered service worker'); console.log('Registering push'); const subscription = await registration.pushManager. subscribe({ userVisibleOnly: true, // `urlBase64ToUint8Array()` 函數與如下網址中的描述一致 // https://www.npmjs.com/package/web-push#using-vapid-key-for-applicationserverkey applicationServerKey: urlBase64ToUint8Array(publicVapidKey) }); console.log('Registered push'); console.log('Sending push'); await fetch('/subscribe', { method: 'POST', body: JSON.stringify(subscription), headers: { 'content-type': 'application/json' } }); console.log('Sent push'); } 複製代碼
最後,你須要實現 client.js
所加載的 worker.js
文件。 這個文件是 service worker 邏輯所在之處。當訂閱者接受到一個推送消息時,service worker 將收到一個 'push' 事件。github
console.log('Loaded service worker!'); self.addEventListener('push', ev => { const data = ev.data.json(); console.log('Got push', data); self.registration.showNotification(data.title, { body: 'Hello, World!', icon: 'http://mongoosejs.com/docs/images/mongoose5_62x30_transparent.png' }); }); 複製代碼
好了!配置正確的環境變量並啓動你的服務:
$ env PUBLIC_VAPID_KEY='OMITTED' env PRIVATE_VAPID_KEY='OMITTED' node . 複製代碼
在 Chrome 中訪問 http://localhost:3000
,你應該能夠看到下面的推送通知!
這種通知不只在 Chrome 中可用,在 Firefox 也能夠用一樣的代碼實現。
Web 推送只是 service workers 帶來的諸多好處的其中一種。 經過一個 npm 模組,你就能給大多數現代瀏覽器推送通知。下次你要爲你的 web 應用增長推送通知功能的時候,記得用 service workers 哦!
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。