Appearance
消息推送 API
概述
基于 Web Push API(VAPID 协议),支持 H5 端浏览器消息推送。
获取 VAPID 公钥
获取服务端 VAPID 公钥,前端用于订阅 Push 通知。无需认证。
GET /api/push/public-key响应示例
json
{
"code": 200,
"publicKey": "BHxKwG3...(Base64 编码的公钥)"
}保存推送订阅
前端通过 PushManager.subscribe() 获取订阅对象后,发送到服务端保存。无需认证。
POST /api/push/subscribe请求体
json
{
"userId": "user_001",
"subscription": {
"endpoint": "https://fcm.googleapis.com/fcm/send/...",
"keys": {
"p256dh": "BNI8p...",
"auth": "tBHHi..."
}
}
}| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| userId | string | 是 | 用户 ID |
| subscription | object|string | 是 | PushSubscription 对象或序列化字符串 |
响应
json
{ "code": 200, "message": "Subscription saved successfully" }发送测试推送
用于调试和验证推送配置是否正确。需要 JWT 认证。
GET /api/push/test-send?userId=user_001查询参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| userId | string | 是 | 目标用户 ID |
响应
成功:
json
{ "code": 200, "message": "Test notification sent!" }无订阅记录:
json
{ "code": 404, "message": "No push subscription found" }前端对接流程
以下是 H5 端开启消息推送的完整流程:
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ 前端页面 │ │ Service │ │ 服务端 │ │ 推送服务 │
│ │ │ Worker │ │ │ │ (FCM等) │
└────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘
│ 1. 请求权限 │ │ │
│────────────────────────────────>│ │
│ 2. 获取公钥 │ │ │
│<────────────────────────────────│ │
│ 3. subscribe │ │ │
│───────────────>│ │ │
│ 4. 返回 subscription │ │
│<───────────────│ │ │
│ 5. 保存订阅 │ │ │
│────────────────────────────────>│ │
│ │ │ 6. 离线消息 │
│ │ │───────────────>│
│ │ │ 7. 推送通知 │
│ │<───────────────────────────────│
│ 8. 显示通知 │ │ │
│<───────────────│ │ │代码示例
javascript
// 1. 检查浏览器支持
if (!('serviceWorker' in navigator) || !('PushManager' in window)) {
console.log('浏览器不支持消息推送');
return;
}
// 2. 请求通知权限
const permission = await Notification.requestPermission();
if (permission !== 'granted') return;
// 3. 获取 VAPID 公钥
const res = await fetch('/api/push/public-key');
const { publicKey } = await res.json();
// 4. 转换公钥为 Uint8Array
const convertedKey = urlBase64ToUint8Array(publicKey);
// 5. 等待 Service Worker 注册完成
const reg = await navigator.serviceWorker.ready;
// 6. 订阅推送
const sub = await reg.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: convertedKey
});
// 7. 将订阅信息发送到服务端保存
await fetch('/api/push/subscribe', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userId: currentUserId,
subscription: sub
})
});iOS 注意事项
iOS Safari 要求将应用"添加到主屏幕(PWA)"后才能使用推送功能。如果订阅失败,需提示用户进行 PWA 安装。