Web-Push 通知脚本适用于 Firefox 但不适用于 Chrome

Web-Push notification script working on Firefox but not on Chrome

我正在构建一个网络推送通知系统,我正在使用本示例中使用的概念:

https://github.com/Minishlink/web-push-php-example

我的 JS 文件中有以下代码。它检查 API 支持,检查通知是否未禁用,注册服务工作者,请求显示通知的权限,如果允许则订阅用户并将详细信息发送到服务器。如果用户已经订阅,它会更新数据库中的端点值。

当我在 Firefox 61 上 运行 它工作正常,但是当我在 Chrome 67 上 运行 它时,我得到这个错误:

Uncaught (in promise) TypeError: Cannot read property 'getKey' of null
    at pushSubscribe (notification.js:48)
    at navigator.serviceWorker.ready.then.then.subscription (notification.js:30)

我的理解是 Chrome 在服务工作人员注册和用户订阅时没有检测到 订阅,因此它给出了错误。有什么解决办法吗?

谢谢。

document.addEventListener('DOMContentLoaded', () => {
    // Feature detection
    if (!('serviceWorker' in navigator)) {
        alert('Service Worker API isn’t supported.');
    } else if (!('PushManager' in window)) {
        alert('Push API isn’t supported.');
    } else if (!('Notification' in window)) {
        alert('Notifications API isn’t supported.');
    } else if (!('showNotification' in ServiceWorkerRegistration.prototype)) {
        alert('Notifications aren’t supported.');

    // Check permission
    } else if (Notification.permission == 'denied') {
        alert('Notifications are disabled.');
    } else {

        // Register service worker
        navigator.serviceWorker.register('/service-worker.js').then(() => {
            navigator.serviceWorker.ready.then(serviceWorkerRegistration => serviceWorkerRegistration.pushManager.getSubscription()).then(subscription => {
                if (!subscription) {
                    // Subscribe user
                    navigator.serviceWorker.ready.then(serviceWorkerRegistration => serviceWorkerRegistration.pushManager.subscribe({
                        userVisibleOnly: true,
                        applicationServerKey: urlBase64ToUint8Array('BNwjaNBKGM13IAef-gJr7C95W3yLJe2F5X0zLnwacN3zCnZK15Vqf3ijeHl9k7K0yBFX3ZwxAmldPoVDpi6iETA'),
                    })).then(subscription => {
                        return pushSubscribe(subscription);
                    });
                }
                // Update endpoint
                return pushSubscribe(subscription);
            });
        });

        function urlBase64ToUint8Array(base64String) {
            const padding = '='.repeat((4 - base64String.length % 4) % 4);
            const base64 = (base64String + padding).replace(/\-/g, '+').replace(/_/g, '/');

            const rawData = window.atob(base64);
            const outputArray = new Uint8Array(rawData.length);

            for (let i = 0; i < rawData.length; ++i) {
                outputArray[i] = rawData.charCodeAt(i);
            }
            return outputArray;
        }

        function pushSubscribe(subscription) {
            const key = subscription.getKey('p256dh');
            const token = subscription.getKey('auth');
            const contentEncoding = (PushManager.supportedContentEncodings || ['aesgcm'])[0];

            return fetch('/scripts/notification-subscribe.php', {
                method: 'POST',
                body: JSON.stringify({
                    endpoint: subscription.endpoint,
                    publicKey: key ? btoa(String.fromCharCode.apply(null, new Uint8Array(key))) : null,
                    authToken: token ? btoa(String.fromCharCode.apply(null, new Uint8Array(token))) : null,
                    contentEncoding,
                    user: userId, // generated beforehand
                }),
            }).then(() => subscription);
        }
    }
});
        if(subscription){
const key = subscription.getKey('p256dh');
            const token = subscription.getKey('auth');
            const contentEncoding = (PushManager.supportedContentEncodings || ['aesgcm'])[0];

            return fetch('/scripts/notification-subscribe.php', {
                method: 'POST',
                body: JSON.stringify({
                    endpoint: subscription.endpoint,
                    publicKey: key ? btoa(String.fromCharCode.apply(null, new Uint8Array(key))) : null,
                    authToken: token ? btoa(String.fromCharCode.apply(null, new Uint8Array(token))) : null,
                    contentEncoding,
                    user: 1,
                }),
            }).then(() => subscription);
        }
}

Just modify this function hope pushSubscription with if block it works