CDN Web Push是一种将Web推送通知的投递能力下沉到内容分发网络边缘节点的技术方案。传统Web Push依赖应用服务器直接调用浏览器推送服务(如FCM、Mozilla Push Service),当源站故障或网络拥塞时,通知无法及时下发。引入CDN后,边缘节点可以接管订阅信息的管理与推送请求的转发,使通知链路更健壮。本节先说明基础原理,后续逐步展开集成方式与常见问题。

Web Push的基础技术构成
Web Push的核心由三项浏览器能力组成:Service Worker、Push API和Notification API。Service Worker是运行在浏览器后台的脚本,即使用户关闭了页面也能接收事件。Push API允许网页向推送服务发起订阅,获得一个包含两个关键字段的订阅对象:endpoint(推送服务分配给该用户的URL)和keys(用于加密载荷的密钥)。Notification API则负责在系统层弹出提示框。
在鉴权方面,规范定义了VAPID(Voluntary Application Server Identification)机制。服务器使用椭圆曲线密钥对生成JWT令牌,证明自己有权对该订阅发起推送。如果不带VAPID,部分推送服务会拒绝请求。下面是一段Node.js中生成VAPID令牌的简化示例:
const webpush = require('web-push');
const vapidKeys = webpush.generateVAPIDKeys();
webpush.setVapidDetails(
'mailto:admin@ipipp.com',
vapidKeys.publicKey,
vapidKeys.privateKey
);
const token = webpush.getVAPIDHeaders(
'https://push.ippipp.com',
'audience',
vapidKeys.publicKey,
vapidKeys.privateKey,
'admin@ipipp.com'
);
console.log(token);
上述代码展示了密钥生成与头部构造过程。实际生产环境应将私钥保存在环境变量或密钥管理服务中,切勿前端暴露。加密载荷部分需使用订阅中的p256dh和auth字段,通过ECDH协商出对称密钥,再用AES128GCM加密消息体,保证传输内容仅用户浏览器可解密。
CDN在推送链路中的角色与集成
将CDN引入Web Push,主要解决两个问题:一是源站与推送服务之间的网络不稳定,二是海量订阅下的连接复用。典型架构中,CDN边缘节点提供订阅接收接口,浏览器调用该接口上报endpoint与密钥,边缘将元数据写入就近的KV存储,并异步同步至全局。当业务系统要发通知时,只须向CDN的推送网关发送一次请求,由网关并行调用各推送服务。
这样的设计让源站从“逐一对接百万endpoint”中解放出来。CDN网关还能做限流与重试,避免触发推送服务的速率限制。以下示例展示边缘函数如何代理推送请求,注意代码中的HTML特殊字符已转义:
addEventListener('fetch', event => {
const url = new URL(event.request.url);
if (url.pathname === '/push') {
event.respondWith(handlePush(event.request));
}
});
async function handlePush(req) {
const body = await req.json();
const subscription = body.subscription;
const payload = JSON.stringify({ title: '新消息', body: '来自CDN' });
const response = await fetch(subscription.endpoint, {
method: 'POST',
headers: { 'TTL': '60', 'Content-Type': 'application/octet-stream' },
body: payload
});
return new Response('ok', { status: 200 });
}
在真实场景中,边缘函数通常不会直接发起推送,而是将任务放入队列,由专门的中转服务处理VAPID签名与加密,从而隔离密钥与公网入口。同时,CDN可以缓存“用户在线状态”的短时效标记,减少向离线设备无效投递造成的配额浪费。这种分层使系统具备更好的弹性。
部署中的常见陷阱与优化思路
许多团队在试用CDN Web Push时会遇到“幽灵订阅”问题:用户已取消授权,但源站仍保留旧endpoint,导致推送返回410状态码却不清理。正确做法是监听推送服务返回的订阅失效响应,并触发CDN边缘的删除接口。下表对比了两种处理方式的差异:
| 策略 | 源站主动清理 | 边缘自动失效 |
|---|---|---|
| 触发条件 | 收到410后写库 | 边缘KV设置TTL并监听回调 |
| 一致性 | 弱,易漏删 | 强,就近过期 |
| 运维成本 | 高 | 低 |
另一个容易被忽视的点是证书与混合内容。如果页面以HTTPS加载,但推送脚本或订阅接口运行在HTTP边缘域名下,浏览器会拦截注册Service Worker。应确保CDN全站启用有效证书,且<script>引入路径与Scope一致。此外,部分老旧代理会缓冲POST请求,使推送延迟数分钟,此时需要调整CDN的缓冲策略或改用分块传输。
性能层面,建议对通知内容做体积压缩,因为多数推送服务限制载荷不超过4096字节。若需传递复杂数据,可仅在推送中放入摘要与ID,浏览器收到后通过<fetch>向CDN拉取详情。这种“轻推重拉”模式既省流量又避开了加密体积上限,配合边缘缓存可让详情接口命中率超过九成。
CDNWeb_Pushserver_push修改时间:2026-08-18 09:40:16