Abonnieren eines Nutzers

Matt Gaunt

Zuerst holen wir die Berechtigung des Nutzers ein, ihm Push-Nachrichten zu senden. PushSubscription ausprobieren.

Die JavaScript API hierfür ist relativ einfach. Lassen Sie uns durch den logischen Fluss.

Funktionserkennung

Zunächst müssen wir überprüfen, ob der aktuelle Browser Push-Nachrichten unterstützt. Wir können prüfen, Push wird durch zwei einfache Prüfungen unterstützt.

  1. Suchen Sie im Navigator nach serviceWorker.
  2. Suchen Sie nach PushManager für window.
if (!('serviceWorker' in navigator)) {
  // Service Worker isn't supported on this browser, disable or hide UI.
  return;
}

if (!('PushManager' in window)) {
  // Push isn't supported on this browser, disable or hide UI.
  return;
}

Während die Browserunterstützung sowohl für Service Worker als auch ist es immer sinnvoll, die Erkennungsfunktion sowohl für Progressive verbessern.

Service Worker registrieren

Durch diese Funktion wissen wir, dass sowohl Service Worker als auch Push unterstützt werden. Der nächste Schritt ist das „Registrieren“, unserem Service Worker.

Wenn wir einen Service Worker registrieren, teilen wir dem Browser mit, wo sich die Service Worker-Datei befindet. In der Datei handelt es sich immer noch nur um JavaScript, aber der Browser „gewährt ihr Zugriff“ an den Service Worker senden APIs, einschließlich Push. Genauer gesagt führt der Browser die Datei in einem Service Worker aus. zu verbessern.

Rufen Sie zum Registrieren eines Service Workers navigator.serviceWorker.register() auf und übergeben Sie den Pfad zu unserer Datei. Beispiel:

function registerServiceWorker() {
  return navigator.serviceWorker
    .register('/service-worker.js')
    .then(function (registration) {
      console.log('Service worker successfully registered.');
      return registration;
    })
    .catch(function (err) {
      console.error('Unable to register service worker.', err);
    });
}

Diese Funktion teilt dem Browser mit, dass es eine Service Worker-Datei gibt und wo diese sich befindet. In In diesem Fall befindet sich die Service Worker-Datei unter /service-worker.js. Hinter den Kulissen des Browsers führt nach dem Aufruf von register() die folgenden Schritte aus:

  1. Laden Sie die Service Worker-Datei herunter.

  2. Führen Sie den JavaScript-Code aus.

  3. Wenn alles korrekt ausgeführt wird und keine Fehler vorliegen, wird das von register() zurückgegebene Promise zurückgegeben. behoben werden. Bei Fehlern jeglicher Art wird das Versprechen abgelehnt.

Wenn register() die Anfrage ablehnt, prüfe deinen JavaScript-Code in den Chrome-Entwicklertools auf Tippfehler oder Fehler.

Wenn register() aufgelöst wird, wird ein ServiceWorkerRegistration zurückgegeben. Wir verwenden diese -Registrierung, um auf die PushManager API zuzugreifen.

Browserkompatibilität mit der PushManager API

Unterstützte Browser

  • Chrome: 42. <ph type="x-smartling-placeholder">
  • Edge: 17. <ph type="x-smartling-placeholder">
  • Firefox: 44. <ph type="x-smartling-placeholder">
  • Safari: 16. <ph type="x-smartling-placeholder">

Quelle

Berechtigung wird angefordert

Wir haben unseren Service Worker registriert und sind nun bereit, den Nutzer zu abonnieren. Der nächste Schritt ist das um Push-Nachrichten zu senden.

Die API zum Anfordern von Berechtigungen ist relativ einfach. Der Nachteil ist, dass Die API wurde kürzlich von der Ausführung eines Callbacks in die Rückgabe eines Promise-Objekts geändert. Die dass wir nicht erkennen können, welche API-Version Daher müssen Sie beide implementieren und beide verarbeiten.

function askPermission() {
  return new Promise(function (resolve, reject) {
    const permissionResult = Notification.requestPermission(function (result) {
      resolve(result);
    });

    if (permissionResult) {
      permissionResult.then(resolve, reject);
    }
  }).then(function (permissionResult) {
    if (permissionResult !== 'granted') {
      throw new Error("We weren't granted permission.");
    }
  });
}

Das wichtige Code-Snippet im obigen Code ist der Aufruf an Notification.requestPermission() Bei dieser Methode wird dem Nutzer eine Eingabeaufforderung angezeigt:

Berechtigungsaufforderung in Chrome auf Computern und Mobilgeräten.

Sobald der Nutzer mit der Berechtigungsaufforderung interagiert hat, indem er auf „Zulassen“, „Blockieren“ oder „Schließen“ klickt, wird das Ergebnis als String übergeben: 'granted', 'default' oder 'denied'.

Im Beispielcode oben wird das von askPermission() zurückgegebene Promise aufgelöst, wenn die Berechtigung Andernfalls wird ein Fehler ausgegeben, sodass das Versprechen abgelehnt wird.

Ein Grenzfall, den Sie behandeln müssen, ist, wenn die Nutzenden auf die Schaltfläche Schaltfläche. Wenn dieses kann Ihre Web-App den Nutzer nicht noch einmal um Erlaubnis fragen. Sie müssen „Blockierung aufheben“ manuell für deine App durch Ändern des Berechtigungsstatus. Dieser ist verborgen. in einem Einstellungsbereich. Überlegen Sie genau, wie und wann Sie die Nutzenden um Erlaubnis bitten, Denn wenn sie auf „Blockieren“ klicken, lässt sich die Entscheidung nicht ohne Weiteres rückgängig machen.

Die gute Nachricht ist, dass die meisten Nutzenden gerne die Berechtigung erteilen, wissen sie, warum die Berechtigung angefordert wird.

Wir sehen uns später an, wie einige beliebte Websites um Erlaubnis bitten.

Nutzer mit PushManager abonnieren

Sobald unser Service Worker registriert ist und wir die entsprechende Berechtigung erhalten haben, können wir einen Nutzer abonnieren, registration.pushManager.subscribe() wird angerufen.

function subscribeUserToPush() {
  return navigator.serviceWorker
    .register('/service-worker.js')
    .then(function (registration) {
      const subscribeOptions = {
        userVisibleOnly: true,
        applicationServerKey: urlBase64ToUint8Array(
          'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U',
        ),
      };

      return registration.pushManager.subscribe(subscribeOptions);
    })
    .then(function (pushSubscription) {
      console.log(
        'Received PushSubscription: ',
        JSON.stringify(pushSubscription),
      );
      return pushSubscription;
    });
}

Beim Aufrufen der Methode subscribe() übergeben Sie ein options-Objekt, das aus beiden erforderliche und optionale Parameter.

Sehen wir uns alle Optionen an, die wir übergeben können.

userVisibleOnly-Optionen

Als die Push-Funktion zum ersten Mal in den Browsern eingeführt wurde, war unsicher, ob Entwickler eine Push-Nachricht zu senden und keine Benachrichtigung anzuzeigen. Dies wird allgemein als „Lautlos“ bezeichnet. da die Nutzenden nicht wussten, dass etwas im Hintergrund passiert ist.

Sie befürchteten, dass Entwickler beispielsweise den Standort eines Nutzers auf einem ohne dass die Nutzenden wissen.

Um dieses Szenario zu vermeiden und den Autoren der Spezifikationen Zeit zu geben, darüber nachzudenken, wie dies am besten unterstützt werden kann wurde die Option userVisibleOnly hinzugefügt. Die Übergabe des Werts true ist eine symbolische Zustimmung des Browsers, dass die Web-App bei jeder Übertragung eine Benachrichtigung anzeigt. empfangen (d.h. keine stille Push-Übertragung).

Derzeit müssen Sie den Wert true übergeben. Wenn Sie das Tag userVisibleOnly-Schlüssel oder übergeben Sie false, erhalten Sie den folgenden Fehler:

Chrome unterstützt die Push API derzeit nur für Abos, die zu für den Nutzer sichtbare Nachrichten. Dies können Sie durch Aufrufen Stattdessen pushManager.subscribe({userVisibleOnly: true}). Weitere Informationen finden Sie unter https://goo.gl/yqv4Q4.

Derzeit sieht es so aus, als würde eine pauschale stille Push-Funktion in Chrome nie implementiert werden. Stattdessen Spezifikationsautoren erforschen das Konzept einer Budget-API, die Web-Apps Anzahl der Push-Nachrichten im Hintergrund basierend auf der Nutzung einer Web-App

Option „applicationServerKey“

Wir haben kurz „Anwendungsserverschlüssel“ im vorherigen Abschnitt. "Anwendung Serverschlüssel“ werden von einem Push-Dienst verwendet, um die Anwendung zu identifizieren, die einen Nutzer abonniert, um sicherzustellen, dass dieselbe Anwendung Nachrichten an den Nutzer sendet.

Anwendungsserverschlüssel sind öffentliche und private Schlüsselpaare, die für Ihre Anwendung eindeutig sind. Der private Schlüssel sollte für Ihre Anwendung geheim gehalten werden und kann geteilt werden. frei wählbar.

Die an den subscribe()-Aufruf übergebene Option applicationServerKey ist das öffentliche Objekt der Anwendung . Der Browser gibt dies beim Abonnieren des Nutzers an einen Push-Dienst weiter, d. h. die Push-Benachrichtigung -Dienst kann den öffentlichen Schlüssel Ihrer Anwendung mit dem PushSubscription des Nutzers verknüpfen.

Das folgende Diagramm veranschaulicht diese Schritte.

  1. Ihre Webanwendung wird in einem Browser geladen und Sie rufen subscribe() auf, um Ihre öffentlichen des Anwendungsserverschlüssels.
  2. Der Browser sendet dann eine Netzwerkanfrage an einen Push-Dienst, der einen Endpunkt generiert, verknüpfen Sie diesen Endpunkt mit dem öffentlichen Schlüssel der Anwendung und geben den Endpunkt an den Browser.
  3. Der Browser fügt diesen Endpunkt zum PushSubscription hinzu, der über den subscribe() versprechen.

Abbildung des öffentlichen Anwendungsserverschlüssels, der in „Abonnieren“ verwendet wird
.

Wenn Sie später eine Push-Nachricht senden möchten, müssen Sie einen Authorization-Header erstellen. Diese Datei enthält Informationen, die mit dem privaten Schlüssel Ihres Anwendungsservers signiert sind. Wenn der Parameter Push-Dienst eine Anfrage zum Senden einer Push-Nachricht erhält, kann er diesen signierten Authorization-Header validieren. indem Sie nach dem öffentlichen Schlüssel suchen, der mit dem Endpunkt verknüpft ist, an den die Anfrage gesendet wird. Wenn die Signatur der Push-Dienst weiß, dass er vom Anwendungsserver stammen muss, entsprechenden privaten Schlüssels. Es ist im Grunde eine Sicherheitsmaßnahme, die verhindert, dass jemand anderes Nachrichten an die Nutzer einer Anwendung zu senden.

Wie der private Anwendungsserverschlüssel beim Senden eines
Nachricht

Technisch gesehen ist die applicationServerKey optional. Am einfachsten ist es aber, die Implementierung in Chrome erfordert, und für andere Browser in die Zukunft zu führen. Bei Firefox ist dies optional.

Die Spezifikation, die definiert, wie der Anwendungsserverschlüssel sein sollte, lautet die VAPID-Spezifikation Wenn Sie etwas lesen, das sich auf "Anwendungsserverschlüssel" oder "VAPID-Schlüssel", aber denken Sie daran, dass es sich um denselben Wert handelt.

Anwendungsserverschlüssel erstellen

Sie können einen öffentlichen und privaten Satz von Anwendungsserverschlüsseln erstellen. Rufen Sie dazu web-push-codelab.glitch.me oder Sie können den Web-Push-Befehlszeile , um Schlüssel zu generieren. Gehen Sie dazu so vor:

    $ npm install -g web-push
    $ web-push generate-vapid-keys

Sie müssen diese Schlüssel nur einmal für Ihre Anwendung erstellen. Behalten Sie jedoch den Schlüssel der private Schlüssel privat ist. (Ja, das habe ich gerade gesagt.)

Berechtigungen und „Subscribe()“

Das Aufrufen von subscribe() hat einen Nebeneffekt. Wenn Ihre Webanwendung keine Berechtigungen für zum Zeitpunkt des Aufrufs von subscribe() eine Benachrichtigung anzeigt, fordert der Browser Berechtigungen für Sie. Dies ist nützlich, wenn Ihre Benutzeroberfläche mit diesem Ablauf funktioniert, Sie aber mehr Kontrolle (und ich denke, die meisten Entwickler werden dies tun), sich an die Notification.requestPermission() API halten die wir zuvor verwendet haben.

Was ist ein PushSubscription?

Wir nennen subscribe(), übergeben einige Optionen und erhalten im Gegenzug ein Versprechen, das PushSubscription führt zu einem Code wie diesem:

function subscribeUserToPush() {
  return navigator.serviceWorker
    .register('/service-worker.js')
    .then(function (registration) {
      const subscribeOptions = {
        userVisibleOnly: true,
        applicationServerKey: urlBase64ToUint8Array(
          'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U',
        ),
      };

      return registration.pushManager.subscribe(subscribeOptions);
    })
    .then(function (pushSubscription) {
      console.log(
        'Received PushSubscription: ',
        JSON.stringify(pushSubscription),
      );
      return pushSubscription;
    });
}

Das Objekt PushSubscription enthält alle erforderlichen Informationen zum Senden eines Push-Vorgangs. Nachrichten an diesen Nutzer senden. Wenn Sie den Inhalt mit JSON.stringify() ausdrucken, sehen Sie die Meldung Folgendes:

    {
      "endpoint": "https://some.pushservice.com/something-unique",
      "keys": {
        "p256dh":
    "BIPUL12DLfytvTajnryr2PRdAgXS3HGKiLqndGcJGabyhHheJYlNGCeXl1dn18gSJ1WAkAPIxr4gK0_dQds4yiI=",
        "auth":"FPssNDTKnInHVndSTdbKFw=="
      }
    }

endpoint ist die URL der Push-Dienste. Stellen Sie eine POST-Anfrage, um eine Push-Nachricht auszulösen. an diese URL an.

Das Objekt keys enthält die Werte zum Verschlüsseln von Nachrichtendaten, die mit einer Push-Nachricht gesendet werden (auf die wir später in diesem Abschnitt eingehen werden).

Regelmäßige Verlängerung des Abos, um das Ablaufdatum zu verhindern

Wenn Sie Push-Benachrichtigungen abonnieren, erhalten Sie häufig einen PushSubscription.expirationTime von null. Theoretisch bedeutet das, dass das Abo nie abläuft (im Gegensatz zu einem DOMHighResTimeStamp, das Ihnen den genauen Zeitpunkt angibt, an dem das Abo abläuft). In der Praxis ist es jedoch üblich, dass Browser Abos ablaufen, z. B. wenn über einen längeren Zeitraum keine Push-Benachrichtigungen empfangen wurden oder wenn der Browser feststellt, dass der Nutzer keine App mit der Berechtigung für Push-Benachrichtigungen verwendet. Ein Muster, um dies zu verhindern, besteht darin, den Nutzer nach jeder empfangenen Benachrichtigung erneut zu abonnieren, wie im folgenden Snippet gezeigt. Dies erfordert, dass Sie Benachrichtigungen häufig genug senden, damit der Browser das Abonnement nicht automatisch abläuft. Wägen Sie außerdem sorgfältig die Vor- und Nachteile legitimer Benachrichtigungen gegen unbeabsichtigtes Spamming des Nutzers ab, nur damit das Abonnement nicht abläuft. Letztendlich sollten Sie nicht versuchen, den Browser zu bekämpfen, um Nutzer vor längst vergessenen abonnierten Benachrichtigungen zu schützen.

/* In the Service Worker. */

self.addEventListener('push', function(event) {
  console.log('Received a push message', event);

  // Display notification or handle data
  // Example: show a notification
  const title = 'New Notification';
  const body = 'You have new updates!';
  const icon = '/images/icon.png';
  const tag = 'simple-push-demo-notification-tag';

  event.waitUntil(
    self.registration.showNotification(title, {
      body: body,
      icon: icon,
      tag: tag
    })
  );

  // Attempt to resubscribe after receiving a notification
  event.waitUntil(resubscribeToPush());
});

function resubscribeToPush() {
  return self.registration.pushManager.getSubscription()
    .then(function(subscription) {
      if (subscription) {
        return subscription.unsubscribe();
      }
    })
    .then(function() {
      return self.registration.pushManager.subscribe({
        userVisibleOnly: true,
        applicationServerKey: urlBase64ToUint8Array('YOUR_PUBLIC_VAPID_KEY_HERE')
      });
    })
    .then(function(subscription) {
      console.log('Resubscribed to push notifications:', subscription);
      // Optionally, send new subscription details to your server
    })
    .catch(function(error) {
      console.error('Failed to resubscribe:', error);
    });
}

Abo an Ihren Server senden

Sobald Sie ein Push-Abo haben, sollten Sie es an Ihren Server senden. Es liegt an Ihnen, wie Sie Ein kleiner Tipp ist, JSON.stringify() zu verwenden, um alle notwendigen Daten -Aboobjekt. Alternativ können Sie dieselben manuell so:

const subscriptionObject = {
  endpoint: pushSubscription.endpoint,
  keys: {
    p256dh: pushSubscription.getKeys('p256dh'),
    auth: pushSubscription.getKeys('auth'),
  },
};

// The above is the same output as:

const subscriptionObjectToo = JSON.stringify(pushSubscription);

Das Abo wird auf der Webseite wie folgt gesendet:

function sendSubscriptionToBackEnd(subscription) {
  return fetch('/api/save-subscription/', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(subscription),
  })
    .then(function (response) {
      if (!response.ok) {
        throw new Error('Bad status code from server.');
      }

      return response.json();
    })
    .then(function (responseData) {
      if (!(responseData.data && responseData.data.success)) {
        throw new Error('Bad response from server.');
      }
    });
}

Der Knotenserver empfängt diese Anfrage und speichert die Daten zur späteren Verwendung in einer Datenbank.

app.post('/api/save-subscription/', function (req, res) {
  if (!isValidSaveRequest(req, res)) {
    return;
  }

  return saveSubscriptionToDatabase(req.body)
    .then(function (subscriptionId) {
      res.setHeader('Content-Type', 'application/json');
      res.send(JSON.stringify({data: {success: true}}));
    })
    .catch(function (err) {
      res.status(500);
      res.setHeader('Content-Type', 'application/json');
      res.send(
        JSON.stringify({
          error: {
            id: 'unable-to-save-subscription',
            message:
              'The subscription was received but we were unable to save it to our database.',
          },
        }),
      );
    });
});

Mit den PushSubscription-Details auf unserem Server können wir unseren Nutzer jederzeit eine Nachricht senden.

Regelmäßige Verlängerung des Abos, um das Ablaufdatum zu verhindern

Wenn Sie Push-Benachrichtigungen abonnieren, erhalten Sie häufig einen PushSubscription.expirationTime von null. Theoretisch bedeutet das, dass das Abo nie abläuft (im Gegensatz zu einem DOMHighResTimeStamp, das Ihnen den genauen Zeitpunkt angibt, an dem das Abo abläuft). In der Praxis ist es jedoch üblich, dass Browser Abos ablaufen, z. B. wenn über einen längeren Zeitraum keine Push-Benachrichtigungen empfangen wurden oder der Browser feststellt, dass der Nutzer die App mit der Berechtigung für Push-Benachrichtigungen nicht verwendet. Ein Muster, um dies zu verhindern, besteht darin, den Nutzer nach jeder empfangenen Benachrichtigung erneut zu abonnieren, wie im folgenden Snippet gezeigt. Dies erfordert, dass Sie Benachrichtigungen häufig genug senden, damit der Browser das Abonnement nicht automatisch abläuft. Wägen Sie außerdem sorgfältig die Vor- und Nachteile legitimer Benachrichtigungen gegen das Versenden von Spam ab, nur damit das Abonnement nicht abläuft. Letztendlich sollten Sie nicht versuchen, den Browser zu bekämpfen, um Nutzer vor längst vergessenen abonnierten Benachrichtigungen zu schützen.

/* In the Service Worker. */

self.addEventListener('push', function(event) {
  console.log('Received a push message', event);

  // Display notification or handle data
  // Example: show a notification
  const title = 'New Notification';
  const body = 'You have new updates!';
  const icon = '/images/icon.png';
  const tag = 'simple-push-demo-notification-tag';

  event.waitUntil(
    self.registration.showNotification(title, {
      body: body,
      icon: icon,
      tag: tag
    })
  );

  // Attempt to resubscribe after receiving a notification
  event.waitUntil(resubscribeToPush());
});

function resubscribeToPush() {
  return self.registration.pushManager.getSubscription()
    .then(function(subscription) {
      if (subscription) {
        return subscription.unsubscribe();
      }
    })
    .then(function() {
      return self.registration.pushManager.subscribe({
        userVisibleOnly: true,
        applicationServerKey: urlBase64ToUint8Array('YOUR_PUBLIC_VAPID_KEY_HERE')
      });
    })
    .then(function(subscription) {
      console.log('Resubscribed to push notifications:', subscription);
      // Optionally, send new subscription details to your server
    })
    .catch(function(error) {
      console.error('Failed to resubscribe:', error);
    });
}

Häufig gestellte Fragen

Hier einige häufig gestellte Fragen:

Kann ich den von einem Browser verwendeten Push-Dienst ändern?

Nein. Der Push-Dienst wird vom Browser ausgewählt. subscribe() aufrufen, stellt der Browser Netzwerkanfragen an den Push-Dienst. um die Details von PushSubscription abzurufen.

Jeder Browser verwendet einen anderen Push-Dienst, haben sie nicht unterschiedliche APIs?

Alle Push-Dienste erwarten dieselbe API.

Diese gängige API wird als Web-Push-Protokoll und beschreibt die Netzwerkanfrage die Ihre Anwendung ausführen muss, um eine Push-Nachricht auszulösen.

Wenn ich ein Abo über einen Desktop-Computer schließe, gilt das auch für das Smartphone?

Leider nicht. Ein Nutzer muss sich in jedem Browser, den er verwenden möchte, für Push registrieren. Nachrichten empfangen über. Es ist auch erwähnenswert, dass dafür Der Nutzer, der die Berechtigung auf jedem Gerät erteilt.

Weitere Informationen

Code labs