如何向网页浏览器发送推送通知?

231
我已经阅读了几个小时关于推送通知 APIWeb 通知 API的内容。我还发现,Google 和 Apple 分别通过 GCM 和 APNS 免费提供推送通知服务。
我正在尝试了解是否可以使用桌面通知实现将推送通知发送到浏览器中,我相信这就是 Web 通知 API 所做的。我看到谷歌文档上有关于如何在 Chrome 中实现这一点的说明here & here
现在我仍然无法理解的是:
  1. 我们能否使用 GCM/APNS 将推送通知发送到包括 Firefox 和 Safari 在内的所有 Web 浏览器中?
  2. 如果不能通过 GCM,我们能否拥有自己的后端来完成同样的工作?
我相信,所有这些问题的答案都可以帮助许多遇到类似困惑的人们。

当然,你可以运行自己的后端,但这很复杂。 - dandavis
5
不复杂。browser-push是一个完整的示例教程,介绍如何在没有第三方服务的情况下向浏览器发送推送通知。https://lahiiru.github.io/browser-push - TRiNE
10个回答

229

这里我正在回答自己的问题。之前构建推送通知服务的人已经回答了我所有的疑问。

更新(2022年5月):这是来自谷歌关于网页推送通知的文档。

从Mozilla的这篇文章可以详细了解通知API。

Airship的文章介绍了这个主题以及网页推送和应用推送的区别。

回答6年前提出的原始问题:

  1. 我们可以使用GCM/APNS向所有Web浏览器(包括Firefox和Safari)发送推送通知吗?

答案:Google已在2018年4月停用GCM。您现在可以使用Firebase Cloud Messaging(FCM)。这支持所有平台,包括Web浏览器。

  1. 如果不能通过GCM,我们可以自己后端来实现吗?

答案:是的,我们可以从自己的后端发送推送通知。支持所有主要浏览器。

查看谷歌的这个代码实验室,以更好地了解实现方式。

一些教程:

  • 在Django中实现推送通知:此处
  • 使用Flask发送推送通知,可以看这里:这里这里
  • 从Nodejs发送推送通知,可以看这里:这里
  • 使用PHP发送推送通知,可以看这里:这里这里
  • 从Wordpress发送推送通知,可以看这里:这里这里
  • 从Drupal发送推送通知,可以看这里:这里
  • 在各种编程语言中实现自己的后端:

    进一步阅读:

    有没有免费的服务可以做同样的事情? 有一些公司提供类似的免费、付费和免费试用的方案。以下是一些列举的服务:

    1. https://onesignal.com/(免费 | 支持所有平台)
    2. https://firebase.google.com/products/cloud-messaging/(免费)
    3. https://clevertap.com/(有免费计划)
    4. https://goroost.com/

    注意: 选择免费服务时,请务必阅读条款和条件。免费服务通常通过收集用户数据来进行各种目的,包括分析。

    此外,您需要使用HTTPS发送推送通知。但是,您可以通过letsencrypt.org免费获得https。


    2
    你只需要为Push API使用HTTPS,而不需要为Safari使用。 - collimarco
    5
    "onesignal",不错的信息 :3。 - Kokizzu
    4
    如果您不想支付第三方库的费用,这里有一份开发者指南可以帮助您自行编写推送通知功能。http://www.cronj.com/blog/browser-push-notifications-using-javascript/ 该指南还提到了如何处理当您不希望将主站点转移到HTTPs时的情况。(使用Node.js和JavaScript) - Akash Budhia
    5
    OneSignal是免费的,但请注意它从用户那里收集了多少数据。使用前请阅读服务条款:https://onesignal.com/tos - Lemmings19
    2
    LetsEncrypt.org意味着您应该毫无困难地为所有内容获取HTTPS。 - That Realty Programmer Guy
    显示剩余7条评论

    26

    Javier讨论了通知及其当前的限制。

    我的建议是:在等待不支持通知的浏览器追赶时,使用window.postMessage,否则使用Worker.postMessage()来继续使用Web Workers。这些可以作为后备选项,带有对话框消息显示处理程序,以防通知功能测试失败或权限被拒绝。

    通知具有功能和权限检查:

    if (!("Notification" in window) || (Notification.permission === "denied") ) {
        // use (window||Worker).postMessage() fallback ...
    }
    

    14

    这是一种简单的方法,可用于为所有浏览器发送推送通知:https://pushjs.org

    Push.create("Hello world!", {
    body: "How's it hangin'?",
    icon: '/icon.png',
    timeout: 4000,
    onClick: function () {
        window.focus();
        this.close();
     }
    });
    

    14

    您可以通过服务器端事件将数据从服务器推送到浏览器。这实质上是一个单向流,客户端可以从浏览器“订阅”该流。从这里开始,您可以在SSE流入浏览器时创建新的Notification对象:

    var source = new EventSource('/events');
    
    source.on('message', message => {
      var notification = new Notification(message.title, {
        body: message.body
      });
    }); 
    

    虽然有点老,但是这篇由Eric Bidelman撰写的文章解释了SSE的基础知识,并且还提供了一些服务器端代码示例。


    11

    我假设您说的是真正的推送通知,即使用户没有浏览您的网站也可以传递(否则请查看WebSockets或类似长轮询的遗留方法)。

    我们可以使用 GCM/APNS 发送推送通知到包括 Firefox 和 Safari 在内的所有 Web 浏览器吗?

    GCM 只适用于 Chrome,APNs 只适用于 Safari。每个浏览器制造商都提供自己的服务。

    如果不通过 GCM,我们可以有自己的后端来完成同样的工作吗?

    Push API 需要两个后端!一个由浏览器制造商提供,并负责将通知传递到设备。另一个应该是您的(或者您可以使用第三方服务,如Pushpad),负责触发通知并联系浏览器制造商的服务(即 GCM、APNs、Mozilla 推送服务器)。

    披露:我是 Pushpad 的创始人


    11

    7

    我可以把你的问题重新定义如下

    我们能否拥有自己的后端来发送Chrome、Firefox、Opera和Safari的推送通知?

    是的。截至今天(2017年5月),您可以使用相同的客户端和服务器端实现来处理Chrome、Firefox和Opera(不包括Safari)。因为它们都以相同的方式实现了Web推送通知,即W3C的Push API协议。但Safari有自己的旧架构,所以我们必须单独维护Safari。

    请参考browser-push存储库,了解如何使用自己的后端为您的Web应用程序实现Web推送通知的指南。它通过示例解释了如何为您的Web应用程序添加Web推送通知支持,而无需任何第三方服务。


    5

    目前GCM只适用于chrome和android,类似地,firefox和其他浏览器也有自己的api。

    现在来谈如何实现推送通知,以便它可在所有常见浏览器中使用自己的后端。

    1. 您需要客户端脚本代码,即service worker,参考(Google推送通知)。虽然对于其他浏览器来说这仍然是一样的。

    2.使用Ajax获取端点后,将其保存与浏览器名称一起。

    3.您需要创建后端,其中包含标题、消息、图标、点击URL等字段,根据您的要求。现在,在单击“发送通知”后,调用一个名为send_push()的函数。在此编写各种浏览器的代码,例如

    3.1. 对于chrome

     $headers = array(
              'Authorization: key='.$api_key(your gcm key),
              'Content-Type: application/json',
         );
       $msg = array('to'=>'register id saved to your server');
       $url = 'https://android.googleapis.com/gcm/send';
       $ch = curl_init();
    
          // Set the url, number of POST vars, POST data
          curl_setopt($ch, CURLOPT_URL, $url);
          curl_setopt($ch, CURLOPT_POST, true);
          curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
          curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
          curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($msg));
    
          $result = curl_exec($ch);
    

    3.2. 适用于Mozilla

    $headers = array(            
                  'Content-Type: application/json',
                  'TTL':6000
                );
    
           $url = 'https://updates.push.services.mozilla.com/wpush/v1/REGISTER_ID_TO SEND NOTIFICATION_ON';
    
          $ch = curl_init();
    
          // Set the url, number of POST vars, POST data
          curl_setopt($ch, CURLOPT_URL, $url);
          curl_setopt($ch, CURLOPT_POST, true);
          curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
          curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    
    
          $result = curl_exec($ch);
    

    对于其他浏览器请使用谷歌搜索...


    1

    1

    这里有一个完整的工作HTML示例。
    只需替换图像、文本,就可以开始了!

    <html lang="en">
      <head>
        <meta charset="utf-8" />
    
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        <script src="script.js"></script>
        <link rel="icon" href="favicon.ico" type="image/png">
        <title>Push</title>
    
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
    
      
      </head>
    
      <body>
        <div class="centrado">
    
        
    
    
    <div class="card text-center shadow">
      <div class="card-header">
        Push Notifications 
      </div>
      <div class="card-body">
        <h5 class="card-title">Test for Push Notifications</h5>
        <p class="card-text">Click twice, first for the permission</p>
        <button class="btn btn-danger" id="btn-show-notification">Notify</button>
      </div>
      <div class="card-footer text-muted">
        aledc7
      </div>
    </div>
    
    </div>
    
    
      </body>
    
    
    
    <script>
      $(document).ready(function () {
      $(document).on('DOMContentLoaded', function () {
        // Request desktop notifications permission on page load
    
        if (!Notification) {
          console.log('Notification is not compatible');
          return;
        }
    
        if (Notification.permission !== 'granted') {
          Notification.requestPermission();
        }
      });
    
      function showNotification() {
        if (Notification.permission !== 'granted') {
          Notification.requestPermission();
        } else {
          const options = {
            body: 'Your text for the Notification,
            dir: 'ltr',
            image: 'your_image.png' //must be 728x360px
          };
          const notification = new Notification('Title Notification', options);
    
          notification.onclick = function () {
            window.open('https://stackoverflow.com/users/10220740/ale-dc');
          };
        }
      }
    
      $('#btn-show-notification').on('click', showNotification);
    });
    </script>
    
    
    <style>
      .centrado{
        /* Centrado Horizontal */
        width: 100%;
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
        vertical-align: middle;
    
        /* Centrado Vertical */
        margin: 0;
        position: absolute;
        top: 50%;
        -ms-transform: translateY(-50%);
        transform: translateY(-50%);
    
    
    }
    
    .shadow{
      filter: drop-shadow(2px 4px 8px #585858);
    }
    
    
    </style>
    
    </html>
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接