iOS Safari无法接收后端定时任务发送的Web推送通知问题排查
iOS Safari(含Web App)无法接收后端Web推送通知问题
iOS Web推送是今年推出的新功能,我按指南完成前端实现后,前端发送的通知可正常显示,但后端(PHP)通过Symfony的bentools/webpush-bundle发送的通知,仅在iOS Safari(含Web App)无法接收,MacOS Chrome、Android Chrome等浏览器均正常。
前端实现步骤
- 注册Service Worker
- 申请Notifications权限
- 权限通过后将订阅信息提交至后端存储
前端代码
import convertVapidKey from 'convert-vapid-public-key'; window.addEventListener('load', async () => { // 1. Register ServiceWorker if (!('serviceWorker' in navigator)) { console.warn('[Service Worker] Service Worker is not available for your device or environment!'); return; } let registration; try { registration = await navigator.serviceWorker.register(window.serviceWorkerPath, { scope: '/' }); console.info('[Service Worker] Registration succeeded:', registration); } catch (error) { console.warn('[Service Worker] Registration failed:', error); return; } // 2. Subscribe to Notifications if ( !window.webpushServerKey || !('Notification' in window) || !('PushManager' in window) ) { console.warn('[WebPush Client] Web push is not available for your device or environment!'); return; } try { if (await Notification.requestPermission() === 'granted') { await subscribe(); await registration.showNotification('Congratulations! 🥰', { body: 'You have subscribed to the notifications successfully! 🚀' }); } } catch (error) { console.warn('[WebPush Client] Subscription failed:', error); } async function subscribe() { try { // Subscribe on client const subscription = await registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: convertVapidKey(window.webpushServerKey) }); // Store subscription await fetch('/webpush/', { method: 'POST', mode: 'cors', credentials: 'include', cache: 'default', headers: new Headers({ 'Accept': 'application/json', 'Content-Type': 'application/json' }), body: JSON.stringify({ subscription }) }); console.info('[WebPush Client] Subscription succeeded:', subscription); } catch (error) { console.warn('[WebPush Client] Subscription failed:', error); } } });
Service Worker代码
// sw.js self.addEventListener('push', event => { try { const json = event.data.json(); const title = json.title || ''; const options = json.options || {}; console.info('[Service Worker] Push event received with:', json); event.waitUntil(self.registration.showNotification(title, options)); } catch (error) { console.warn('[Service Worker] Push notification failed:', error); } });
后端发送通知代码
/** @var \BenTools\WebPushBundle\Sender\PushMessageSender */ protected $sender; // ... $message = new \BenTools\WebPushBundle\Model\Message\PushNotification($title, [ PushNotification::BODY => $notification->getBody(), //... ]); $this->sender->push($notification->createMessage(), $subscriptions);
排查情况与疑问
已开启Safari实验性功能中的Notifications、Push API和Service Workers,但MDN浏览器兼容性表显示iOS Safari暂不支持ServiceWorkerGlobalScope的push事件。请问是我的代码存在问题,还是有其他实现方式可以让iOS Safari接收后端推送通知?
内容的提问来源于stack exchange,提问作者Ignas Damunskis
相关产品推荐
相关产品推荐

