- 原文地址: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、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。