【问题标题】:Web-Push notification script working on Firefox but not on ChromeWeb-Push 通知脚本在 Firefox 上工作,但在 Chrome 上不工作
【发布时间】:2018-12-21 13:13:55
【问题描述】:

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

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);
        }
    }
});

【问题讨论】:

  • Chrome 控制台是否有错误
  • @SiddharthJain 是的,Chrome 控制台中显示的错误在问题中。
  • 能否请您在不同级别进行调试,我认为订阅在第一次调用时会变得未定义,您能否在订阅之前测试条件。getKey
  • @SiddharthJain 抱歉,我不清楚如何进行 if 条件检查。 “//注册服务工作者”下的 IF 检查似乎在 Chrome 上也可以正常工作。
  • 在 pushSubscribe 函数中

标签: javascript google-chrome push-notification web-push


【解决方案1】:
        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

【讨论】:

  • 谢谢,这消除了控制台错误。但是我不会在函数中进行检查,而是在调用//注册服务工作者下的函数之前进行。
猜你喜欢
  • 2016-04-11
  • 1970-01-01
  • 1970-01-01
  • 2018-06-14
  • 1970-01-01
  • 1970-01-01
  • 2012-11-23
  • 2016-02-10
  • 1970-01-01
相关资源
最近更新 更多