Skip to content

消息推送 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..."
    }
  }
}
字段类型必填说明
userIdstring用户 ID
subscriptionobject|stringPushSubscription 对象或序列化字符串

响应

json
{ "code": 200, "message": "Subscription saved successfully" }

发送测试推送

用于调试和验证推送配置是否正确。需要 JWT 认证。

GET /api/push/test-send?userId=user_001

查询参数

参数类型必填说明
userIdstring目标用户 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 安装。