使用 Web 推送时遇到的一个难题是,触发推送消息非常“麻烦”。如需触发推送消息,应用需要按照
Web 推送协议
向推送服务发出 POST 请求。如需在所有浏览器中使用推送功能,您需要使用
VAPID
(也称为应用服务器密钥),这基本上需要设置一个值为证明您的应用可以向用户发送消息的标头。如需通过推送消息发送数据,需要对数据进行
加密
,并添加特定标头,以便浏览器能够正确解密消息。
functionsendSubscriptionToBackEnd(subscription){returnfetch('/api/save-subscription/',{method:'POST',headers:{'Content-Type':'application/json',body:JSON.stringify(subscription),.then(function(response){if(!response.ok){thrownewError('Bad status code from server.');returnresponse.json();.then(function(responseData){if(!(responseData.data && responseData.data.success)){thrownewError('Bad response from server.');
constisValidSaveRequest=(req,res)=>{// Check the request body has at least an endpoint.if(!req.body||!req.body.endpoint){// Not a valid subscription.res.status(400);res.setHeader('Content-Type','application/json');res.send(JSON.stringify({error:{id:'no-endpoint',message:'Subscription must have an endpoint.',returnfalse;returntrue;
如果订阅有效,我们需要将其保存并返回适当的 JSON 响应:
returnsaveSubscriptionToDatabase(req.body).then(function(subscriptionId){res.setHeader('Content-Type','application/json');res.send(JSON.stringify({data:{success:true}}));.catch(function(err){res.status(500);res.setHeader('Content-Type','application/json');res.send(JSON.stringify({error:{id:'unable-to-save-subscription',message:'The subscription was received but we were unable to save it to our database.',
consttriggerPushMsg=function(subscription,dataToSend){returnwebpush.sendNotification(subscription,dataToSend).catch((err)=>{if(err.statusCode===404||err.statusCode===410){console.log('Subscription has expired or is no longer valid: ',err);returndeleteSubscriptionFromDatabase(subscription._id);}else{throwerr;
.then(()=>{res.setHeader('Content-Type','application/json');res.send(JSON.stringify({data:{success:true}}));.catch(function(err){res.status(500);res.setHeader('Content-Type','application/json');res.send(JSON.stringify({error:{id:'unable-to-send-messages',message:`We were unable to send messages to all subscriptions : `+`'${err.message}'`