浏览器Web应用推送通知:如何指定非本地Push Server?
Web推送通知:非本地Push Server的订阅逻辑说明
核心逻辑先明确
浏览器不是直接通过你提供的公钥找到你的Push Server,而是借助浏览器厂商自带的推送服务(比如Chrome用Firebase Cloud Messaging,Firefox用Mozilla Push Service)做中转,公钥的作用是身份验证,而非定位你的服务器。
具体流程拆解
订阅阶段的公钥作用
你传入的applicationServerKey是Push Server的公钥,用来让浏览器的推送服务确认:后续只有持有对应私钥的服务器(也就是你的Push Server),才能向这个订阅用户发送推送消息,防止恶意请求。
调用pushManager.subscribe()时,浏览器会和自身的推送服务通信,生成一个包含**推送服务端点(endpoint)**的订阅对象——这个endpoint才是真正用来发推送请求的地址,和你的Push Server地址无关。非本地Push Server的工作步骤
- 用户浏览器调用
subscribe()成功后,你需要把完整的subscription对象(包含endpoint、密钥信息等)发送到你的公网Push Server,存在数据库里。 - 当你要给用户发推送时,你的Push Server用私钥对请求签名,然后向
subscription.endpoint(浏览器推送服务的公网地址)发送POST请求。 - 浏览器的推送服务验证签名通过后,会把消息转发到用户的浏览器,最终由Service Worker接收并展示通知。
- 用户浏览器调用
代码层面的注意点
你当前的订阅代码完全不用改,不管Push Server是本地还是公网,applicationServerKey始终填你的服务器公钥。需要调整的是:
- 确保订阅成功后,把
subscription对象完整同步到公网Push Server存储。 - Push Server端要实现用私钥签名请求、向endpoint发送推送的逻辑,示例伪代码如下:
// Push Server端发送推送的逻辑示例 async function sendPush(subscription, notificationContent) { const pushOptions = { method: 'POST', headers: { 'Content-Type': 'application/json', // 用私钥生成的签名凭证,不同浏览器推送服务的签名格式略有差异 'Authorization': `vapid t=${生成的访问令牌}, k=${你的公钥}` }, body: JSON.stringify({ notification: { title: notificationContent.title, body: notificationContent.body, icon: '/icon.png' } }) }; await fetch(subscription.endpoint, pushOptions); }
内容的提问来源于stack exchange,提问作者DarkTrick
相关产品推荐
相关产品推荐

