javascript - PHP 成功的 webpush 未触发 SW 中的推送事件监听器

标签 javascript php push-notification service-worker progressive-web-apps

我想向网站实现推送通知,但无法触发推送事件 使用 PHP 和 web push library ,尽管看起来消息发送成功。

我尝试从控制台(chrome)触发该事件,并且它有效。

服务人员:

self.addEventListener('install', async event => {
    // works fine
    console.log('install event')
});

self.addEventListener("push", function(event) {
   // console logs work only when I press push button in the console
   console.log( 'push event' );
   console.log( event );
   var data = event.data.json();

   event.waitUntil(self.registration.showNotification(data.title, {

      body: data.body,

      icon: data.icon,

      tag: data.tag

    }));

});

PHP 端点(push.php):

 <?php

 require_once __DIR__ . '/vendor/autoload.php';
 use Minishlink\WebPush\WebPush;
 use Minishlink\WebPush\Subscription;

 $auth = [
     'VAPID' => [
         'subject' => 'mailto:me@website.com', // can be a mailto: or your website address
         'publicKey' => 'BL9qxdhqL_CM1ROLo6AUfeBvEyUuD7EHT3lAz8ksBZSYPsdE6q__uU2FoX9lr5FtmWtlHs-HRMHen3Ki8WWSVA4', // (recommended) uncompressed public key P-256 encoded in Base64-URL
          'privateKey' => '7ldG3QYcY9KStB07ytTnd0CRCVSxbHfHYLyWEmgBKo0', // (recommended) in fact the secret multiplier of the private key encoded in Base64-URL
     ],
 ];

 $subscription = Subscription::create([
       // I'm using post just for test, in production I will fetch endpoints from database
       'endpoint' => $_POST['endpoint'], // I get the value from subscription object
        "keys" => [
            'p256dh' => 'BL9qxdhqL_CM1ROLo6AUfeBvEyUuD7EHT3lAz8ksBZSYPsdE6q__uU2FoX9lr5FtmWtlHs-HRMHen3Ki8WWSVA4',
            'auth' => '7ldG3QYcY9KStB07ytTnd0CRCVSxbHfHYLyWEmgBKo0'
         ],
       'contentEncoding' => 'aesgcm',
   ]);

  $webPush = new WebPush($auth);
  $sent = $webPush->sendNotification($subscription, 'Hi');

  foreach ($webPush->flush() as $report) {
       $endpoint = $report->getRequest()->getUri()->__toString();
       if ($report->isSuccess()) {
            // I get this in the response
            echo "[v] Message sent successfully for subscription {$endpoint}.";
       } else {
            echo "[x] Message failed to sent for subscription {$endpoint}: {$report->getReason()}";
       }
  }

我的 JavaScript:

 async function registerSw () {
    if ('serviceWorker' in navigator) {
        navigator.serviceWorker.register('./sw.js').then(function(registration) {
            subscribeToPush();
        }).catch(error => console.log(error));
    } else {
        alert('Service workers not supported');
    } 
}

 async function subscribeToPush () {
    navigator.serviceWorker.ready.then(function(registration) {

       registration.pushManager.subscribe({

           userVisibleOnly: true,

            applicationServerKey: 
         urlB64ToUint8Array('BL9qxdhqL_CM1ROLo6AUfeBvEyUuD7EHT3lAz8ksBZSYPsdE6q__uU2FoX9lr5FtmWtlHs-HRMHen3Ki8WWSVA4')

  })

  .then(function(subscription) {

    // The subscription was successful
    ajax(subscription);

  })

  .catch(function(e) {

    console.log( e );

  });

});
  }

function urlB64ToUint8Array(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 ajax (subscription) {
      console.log( 'in ajax' );
     console.log( subscription );
      $.ajax({
          url: 'push.php',
          type: 'POST',
          data: {
             'endpoint': subscription.endpoint,
          },
          success: function( response ) {
            // response = JSON.parse( response );
             console.log(typeof response);
            console.log(response);
            // I get message was sent successfuly here
          },
         error: function (xhr, status, error) {
            console.log( xhr.responseText );
        }
     });
   }

Service Worker 注册成功,我可以请求用户权限并将订阅对象中的值发送回后端,网络推送一切正常,但事件仍然没有被触发。

如有任何帮助,我们将不胜感激,谢谢。

最佳答案

可能的问题之一是您需要在服务器上允许 PUT 和 DELETE 类型的请求。

关于javascript - PHP 成功的 webpush 未触发 SW 中的推送事件监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58525667/

相关文章:

ios - 无法使用新的分发证书接收推送通知

ios - 迁移到 aws 后如何使用推送通知

javascript - 使用后备值减少对象数组

javascript - 使用 lodash 重新映射属性名称和值

javascript - jQuery .each 对象排序

php - MySQL 选择连接表作为结果数组

ios - 代码 : why launchOptions in didFinishLaunchingWithOptions always nil?

javascript - chartJs 中折线图下方区域的背景颜色?

javascript - 如何使 HTML Canvas 不可聚焦/不可选择

php - Magento:根据商店进行程序化搜索