使用服务工作者在Node.js中推送通知的入门方法
推送通知是指当手机或Web应用在进行另一项活动时,屏幕上弹出的消息。在现代网络应用中,推送通知有着更广泛的地位。
简介
推送通知可以吸引用户,让他们注意到网络应用中发生的新活动,即使他们没有在使用该应用。
推送通知的好处包括。
- 提高应用程序的参与度,因为用户即使不使用应用程序也会被吸引。
- 通过向用户发送个性化的优惠和广告,提高用户的保留率。
- 跟踪用户指标,以确定应用程序的成功水平。
- 通过向用户方便地提供重要信息,增强用户体验。
目标
在这篇文章中,我们将逐步介绍在Node.js应用程序中使用服务工作者实现推送通知的情况。
前提条件
- 你需要在你的电脑上安装Node.js。
- 对Node.js有基本了解
- 一个代码编辑器。我将使用Visual studio代码。
创建Node.js应用程序
启动应用程序
通过运行以下命令设置Node.js应用程序。
npm init -y
该命令将为我们的应用程序创建一个空的package.json 文件。package.json 将保存项目的元数据,包括依赖性、脚本和版本。
安装依赖项
接下来,我们将安装所需的依赖项。
我们将使用
express作为Node.js的后端框架,body-parser来解析HTTP请求体,web-push来发送应用程序后端触发的消息。
要安装这些依赖项,请在终端运行以下命令。
npm install –save express, body-parser, web-push
构建服务器端
导入依赖项
我们都准备好了。现在,让我们开始实施,创建我们应用程序的服务器端。我们将创建应用程序的入口点,这也将是我们的服务器。
在根目录下,我们将创建一个新的文件,并将其命名为index.js 。在这个文件中,我们将引入我们已安装的依赖项,如下所示。
//Express
const express = require('express');
//web-push
const webpush = require('web-push');
//body-parser
const bodyParser = require('body-parser');
//path
const path = require('path');
//using express
const app = express();
//using bodyparser
app.use(bodyParser.json())
生成VAPID密钥
接下来,我们将为应用程序创建一组VAPID密钥。VAPID(Voluntary Application Server Identification)密钥将允许我们发送推送信息,而不需要建立一个信息服务。它们还能识别谁在发送推送通知。
Vapid密钥成对出现。一个私钥和另一个公钥。
要生成VAPID密钥。在终端运行下面的命令。
./node_modules/.bin/web-push generate-vapid-keys
该命令应该给出如下的密钥。
=======================================
Public Key:
BKd0FOnmkngVtRSf7N3ogMcnnDQGtu5PSMcbzmt_uvrcDTpL424TE6W92qpnMGZPeh1XqHi1rA_MT0iUL0gBXuY
Private Key:
GyXqHJJVtw7uXgCx9mXw9QK65SsCnALClWNHpPHy2pQ
=======================================
请注意,您的Vapid密钥将与我的不同。
通过网络推送设置VAPID密钥
为了设置VAPID密钥,我们首先将我们的密钥存储在变量中,然后调用web-push 模块的setVapiddetails 方法。在index.js 文件中,我们将添加以下代码块。
//storing the keys in variables
const publicVapidKey = 'Your public vapid key';
const privateVapidKey = 'Your private vapid key';
//setting vapid keys details
webpush.setVapidDetails('mailto:mercymeave@section.com', publicVapidKey,privateVapidKey);
创建订阅路由
我们将需要一个路由,客户端在那里发送帖子请求。我们将称这个路由为订阅路由。它将向服务工作者发送通知。下面的代码块指明了如何设置路由。
//subscribe route
app.post('/subscribe', (req, res)=>{
//get push subscription object from the request
const subscription = req.body;
//send status 201 for the request
res.status(201).json({})
//create paylod: specified the detals of the push notification
const payload = JSON.stringify({title: 'Section.io Push Notification' });
//pass the object into sendNotification fucntion and catch any error
webpush.sendNotification(subscription, payload).catch(err=> console.error(err));
})
对客户端进行编码
设置静态路径
现在我们已经设置了我们的服务器。下一步,是对客户端进行编码,从那里发送帖子请求。
首先,我们将在index.js 文件中设置我们的静态文件夹路径。在依赖项下,我们将包括下面这段代码,以指定我们的静态文件夹被称为client 。
//set the static path
app.use(express.static(path.join(__dirname, "client")));
创建所需文件
接下来,在根文件夹中,按照上面的规定创建一个名为client 的文件夹。在客户端文件夹中,我们将创建三个文件。index.js 将有我们的前端代码,一个client.js 用于我们的客户端,一个service.js 用于我们的服务工作者。
在index.html 文件中,我们将为我们的前端添加以下代码。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Push Notification using Node</title>
</head>
<body>
<h1>Section.io push Notification</h1>
<script src="client.js"></script>
</body>
</html>
设置服务工作者
服务工作者是一个由浏览器在后台运行的脚本,它独立于网页,是浏览器和网络之间的桥梁。它通常拦截浏览器中的文档所发出的请求,并将请求重定向到缓存中,以允许离线访问。
为了设置我们的服务工作者,在client.js 文件中,我们将导入我们的公共vapid密钥。
const publicVapidKey = 'Your public key';
接下来,由于我们在网络应用中使用VAPID密钥,我们使用下面的函数将公钥转换为Uint8Array,以传递给订阅调用。
function urlBase64ToUint8Array(base64String) {
const padding = "=".repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, "+")
.replace(/_/g, "/");
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
接下来,我们将检查服务工作者是否在当前浏览器中被启用,并触发发送方法。
//check if the serveice worker can work in the current browser
if('serviceWorker' in navigator){
send().catch(err => console.error(err));
}
在发送方法中,我们将注册服务工作者,然后触发发送通知功能,如下所示。
//register the service worker, register our push api, send the notification
async function send(){
//register service worker
const register = await navigator.serviceWorker.register('/worker.js', {
scope: '/'
});
//register push
const subscription = await register.pushManager.subscribe({
userVisibleOnly: true,
//public vapid key
applicationServerKey: urlBase64ToUint8Array(publicVapidKey)
});
//Send push notification
await fetch("/subscribe", {
method: "POST",
body: JSON.stringify(subscription),
headers: {
"content-type": "application/json"
}
});
}
我们将在worker.js 文件中对下一步进行编码。我们将为推送添加一个事件监听器,并指定推送通知的选项,如标题、正文、图像和图标。我们将在worker.js 文件中添加下面的代码块。
self.addEventListener("push", e => {
const data = e.data.json();
self.registration.showNotification(
data.title, // title of the notification
{
body: "Push notification from section.io", //the body of the push notification
image: "https://pixabay.com/vectors/bell-notification-communication-1096280/",
icon: "https://pixabay.com/vectors/bell-notification-communication-1096280/" // icon
}
);
});
运行服务器
为了测试该应用程序,在index.js 文件中添加下面的代码块。然后在你的终端运行命令npm start 。
const port = 3000;
app.listen(port, ()=>{
console.log(`server started on ${port}`)
});
现在,应用程序将在你每次刷新浏览器时发送推送通知,如下图所示。

结论和进一步阅读
在这篇文章中,我们学习了如何使用服务工作者来实现Web应用程序中的推送通知。