Javascript 管理客户端和服务器端推送通知的订阅
Javascript 管理客户端和服务器端推送通知的订阅,javascript,push-notification,notifications,workbox,Javascript,Push Notification,Notifications,Workbox,我删除了之前关于如何在的文档中使用代码的所有问题,以便更清楚地向您展示我找到的解决方案。 在向您展示代码之前,我将解释我花了很长时间才理解。您通常使用三个与service worker一起工作的文件。在我的例子中,server.js,index.js和sw.js。当浏览器获得显示站点所需的所有文件时,我也会得到index.js文件。此文件使用navigator.serviceworner.register('sw.js')启动服务工作者。然后,它测试用户是否已经接受接收通知。最后,检查订阅是否
我删除了之前关于如何在的文档中使用代码的所有问题,以便更清楚地向您展示我找到的解决方案。
在向您展示代码之前,我将解释我花了很长时间才理解。您通常使用三个与service worker一起工作的文件。在我的例子中,
server.js
,index.js
和sw.js
。当浏览器获得显示站点所需的所有文件时,我也会得到index.js文件。此文件使用navigator.serviceworner.register('sw.js')
启动服务工作者。然后,它测试用户是否已经接受接收通知。最后,检查订阅是否存在,并管理订阅。订阅部分非常重要,而且很难管理。使用
swRegistration.pushManager.subscribe()
我们将获得一个子对象。此对象包含端点、身份验证和P256。这些信息是非常重要的,我们需要发送到我们的服务器将其存储到我们的数据库中。fetch()。通过这种方式,我们将能够在未来向我们的tagerted用户发送通知。
您最不需要知道的是如何创建私有密钥和公共密钥。要生成它,请在终端中显示server.js中myprivateVapidKey
变量下面的console.log。然后将这两个结果复制粘贴到变量中,就像我复制server.js一样,并将paste publicsVapidKey复制到index.js文件中。
server.js:
var express = require('express');
var app = express();
var https = require('https');
var fs = require('fs');
var webPush = require('web-push');
var bodyParser = require('body-parser');
https.createServer({
key: fs.readFileSync('key_localhost2.pem'),
cert: fs.readFileSync('cert_localhost2.pem'),
passphrase: 'localhost',
}, app).listen(8080);
//*****************************************************************
//-------------------------- TEMPLATES --------------------------
//*****************************************************************
//moteur de modèles ou de templates
app.set('view engine', 'ejs');
//*****************************************************************
//-------------------------- MIDDLEWARE --------------------------
//*****************************************************************
app
.use('/static', express.static(__dirname + '/public'))
.use(express.static(__dirname + '/public/js'))
.use(bodyParser.json());
//*****************************************************************
//--------------------------- ROUTES ------------------------------
//*****************************************************************
app.get('/', function (request, response) {
response.render('./pages/index.ejs');
});
var publicVapidKey = "BKwLqQWMQpLfSNGb-VXCsAPE1H5o7Oh3VxDiEIqWWOm2OdAoFPqr9K9WI7dKKtjYYHLTKm7tjJO04091pDXZiJs"
var privateVapidKey = "483sZs2cZUxSQegGKKOZXLl_b7_ywBF_qJO77gXFsHE"
//console.log('Publics keys : ' + vapidKeys.publicKey)
//console.log('Private key : ' + vapidKeys.privateKey)
webPush.setVapidDetails(
'mailto:localhost:8080',
publicVapidKey,
privateVapidKey
);
var pushSubscription;
app.post('/subscription_push_notification', function (req, resp) {
pushSubscription = req.body;
console.log(pushSubscription)
//I'm able to save this information into my database
endpointVal = req.body.endpoint;
authVal = req.body.keys.auth;
p256dhVal = req.body.keys.p256dh;
setTimeout(function () {
if (endpointVal) {
var payload = 'Here is a payload!';
webPush.sendNotification(
pushSubscription,
payload
).catch(function (err) {
console.log(err);
});
}
}, 2000)
resp.json({});
});
index.js:
window.addEventListener('load', function () {
//*********************************************************
// Start SW, permission notification, register subscribe
//*********************************************************
if ('serviceWorker' in navigator) {
//+++++++++++++++++++++++++++++
//Register Service worker
navigator.serviceWorker.register('sw.js')
.then(function (swRegistration) {
//Ask to notification permission
displayNotification();
var publicVapidKey = "BKwLqQWMQpLfSNGb-VXCsAPE1H5o7Oh3VxDiEIqWWOm2OdAoFPqr9K9WI7dKKtjYYHLTKm7tjJO04091pDXZiJs";
var applicationServerKey = urlBase64ToUint8Array(publicVapidKey);
//Manage push notifiaction
swRegistration.pushManager.getSubscription().then(function (sub) {
if (sub === null) {
// Update UI to ask user to register for Push
console.log('Not subscribed to push service!');
swRegistration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: applicationServerKey
}).then(function (sub) {
// We have a subscription, update the database
console.log('Endpoint URL: ', sub.endpoint);
fetch('/subscription_push_notification', {
method: 'POST',
body : JSON.stringify(sub),
headers: {
'content-type':'application/json'
}
});
}).catch(function (e) {
if (Notification.permission === 'denied') {
console.warn('Permission for notifications was denied');
} else {
console.error('Unable to subscribe to push', e);
}
});
} else {
// We have a subscription, update the database
console.log('Subscription object: ', sub);
fetch('/subscription_push_notification', {
method: 'POST',
body : JSON.stringify(sub),
headers: {
'content-type':'application/json'
}
});
}
});
})
.catch(function (err) {
console.log('Service Worker registration failed: ', err);
})
}
//*********************************************************
// Function ask to notification permission
//*********************************************************
function displayNotification() {
if (Notification.permission === 'granted') {
//Mean, the notification is accepted.
console.log('Notification accepted...');
} else if (Notification.permission === "blocked" || Notification.permission === "denied") {
// the user has previously denied notification. Can't reprompt.
console.log('Notification blocked...');
} else {
// show a prompt to the user
console.log('Prompt to accept notification');
Notification.requestPermission();
}
}
//*********************************************************
// Transform public Vapid key
//*********************************************************
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;
}
});
window.addEventListener('load',function(){
//*********************************************************
//启动软件、权限通知、注册和订阅
//*********************************************************
if(导航器中的“serviceWorker”){
//+++++++++++++++++++++++++++++
//注册服务人员
navigator.serviceWorker.register('sw.js')
.然后(功能(SWR注册){
//请求通知许可
显示通知();
var publicVapidKey=“BKWLQWMQPLFSNGB-VxCSAPE1H5O7OH3VxDieiqWWOM2OFPQR9K9WI7DKKTJYYHLTKM7TJJ04091PDXZIJS”;
var applicationServerKey=urlBase64ToUint8Array(publicVapidKey);
//管理推送通知
swRegistration.pushManager.getSubscription().then(函数(子){
if(sub==null){
//更新UI以要求用户注册推送
log('未订阅推送服务!');
swRegistration.pushManager.subscribe({
userVisibleOnly:true,
applicationServerKey:applicationServerKey
}).然后(功能(子){
//我们有订阅,更新数据库
log('endpointurl:',sub.Endpoint);
获取(“/subscription\u push\u通知”{
方法:“POST”,
正文:JSON.stringify(sub),
标题:{
“内容类型”:“应用程序/json”
}
});
}).catch(函数(e){
如果(Notification.permission==='denied'){
console.warn('通知权限被拒绝');
}否则{
控制台错误('无法订阅推送',e);
}
});
}否则{
//我们有订阅,更新数据库
log('Subscription object:',sub);
获取(“/subscription\u push\u通知”{
方法:“POST”,
正文:JSON.stringify(sub),
标题:{
“内容类型”:“应用程序/json”
}
});
}
});
})
.catch(函数(err){
console.log('服务工作者注册失败:',错误);
})
}
//*********************************************************
//函数请求通知权限
//*********************************************************
函数displayNotification(){
如果(Notification.permission===“已授予”){
//也就是说,通知被接受了。
log('接受通知…');
}else if(Notification.permission==“blocked”| | Notification.permission==“denied”){
//用户以前拒绝通知。无法重新请求。
log('Notification blocked…');
}否则{
//向用户显示提示
log(“接受通知的提示”);
Notification.requestPermission();
}
}
//*********************************************************
//转换公钥
//*********************************************************
函数urlBase64ToUint8Array(base64String){
常量填充='='.repeat((4-base64String.length%4)%4);
常量base64=(base64String+填充)
.替换(/\-/g,“+”)
.替换(/_/g,“/”);
const rawData=window.atob(base64);
const outputArray=新的Uint8Array(rawData.length);
for(设i=0;i
sw.js:
window.addEventListener('load', function () {
//*********************************************************
// Start SW, permission notification, register subscribe
//*********************************************************
if ('serviceWorker' in navigator) {
//+++++++++++++++++++++++++++++
//Register Service worker
navigator.serviceWorker.register('sw.js')
.then(function (swRegistration) {
//Ask to notification permission
displayNotification();
var publicVapidKey = "BKwLqQWMQpLfSNGb-VXCsAPE1H5o7Oh3VxDiEIqWWOm2OdAoFPqr9K9WI7dKKtjYYHLTKm7tjJO04091pDXZiJs";
var applicationServerKey = urlBase64ToUint8Array(publicVapidKey);
//Manage push notifiaction
swRegistration.pushManager.getSubscription().then(function (sub) {
if (sub === null) {
// Update UI to ask user to register for Push
console.log('Not subscribed to push service!');
swRegistration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: applicationServerKey
}).then(function (sub) {
// We have a subscription, update the database
console.log('Endpoint URL: ', sub.endpoint);
fetch('/subscription_push_notification', {
method: 'POST',
body : JSON.stringify(sub),
headers: {
'content-type':'application/json'
}
});
}).catch(function (e) {
if (Notification.permission === 'denied') {
console.warn('Permission for notifications was denied');
} else {
console.error('Unable to subscribe to push', e);
}
});
} else {
// We have a subscription, update the database
console.log('Subscription object: ', sub);
fetch('/subscription_push_notification', {
method: 'POST',
body : JSON.stringify(sub),
headers: {
'content-type':'application/json'
}
});
}
});
})
.catch(function (err) {
console.log('Service Worker registration failed: ', err);
})
}
//*********************************************************
// Function ask to notification permission
//*********************************************************
function displayNotification() {
if (Notification.permission === 'granted') {
//Mean, the notification is accepted.
console.log('Notification accepted...');
} else if (Notification.permission === "blocked" || Notification.permission === "denied") {
// the user has previously denied notification. Can't reprompt.
console.log('Notification blocked...');
} else {
// show a prompt to the user
console.log('Prompt to accept notification');
Notification.requestPermission();
}
}
//*********************************************************
// Transform public Vapid key
//*********************************************************
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;
}
});
importScript