Progressive Web-Apps auf Websites mit mehreren Ursprungsservern

Herausforderungen und Problemumgehungen beim Erstellen von progressiven Web-Apps auf Websites mit mehreren Ursprüngen.

Demián Renzulli
Demián Renzulli

Veröffentlicht: 19. August 2019

In der Vergangenheit gab es einige Vorteile bei der Verwendung von Multi-Origin-Architekturen. Für progressive Web-Apps stellt dieser Ansatz viele Herausforderungen dar. Insbesondere die Same-Origin-Policy schränkt die Freigabe von Service Workern, Caches und Berechtigungen ein und erschwert die Bereitstellung einer eigenständigen App über mehrere Ursprünge hinweg.

Hier erfahren Sie, wie Sie mehrere Ursprünge sinnvoll einsetzen und welche Herausforderungen und Problemumgehungen es beim Erstellen von Progressive Web Apps auf Websites mit mehreren Ursprüngen gibt.

Gute und schlechte Verwendung mehrerer Ursprünge

Es gibt einige legitime Gründe für die Verwendung einer Multi-Origin-Architektur, die meist mit der Bereitstellung einer unabhängigen Gruppe von Webanwendungen oder der Erstellung von voneinander vollständig isolierten Umgebungen zusammenhängen. Es gibt auch Verwendungszwecke, die vermieden werden sollten.

Gut gelöste Punkte

Sehen Sie sich zuerst die nützlichen Gründe an:

  • Lokalisierung/Sprache: Verwendung einer länderspezifischen Top-Level-Domain, um Websites für verschiedene Länder zu trennen (z.B. https://www.google.com.ar), oder Verwendung von Subdomains, um Websites für verschiedene Standorte aufzuteilen (z.B.: https://newyork.craigslist.org) oder Inhalte für eine bestimmte Sprache (z.B. https://en.wikipedia.org) anzubieten.

  • Unabhängige Web-Apps: Verwendung verschiedener Subdomains, um Funktionen bereitzustellen, deren Zweck sich erheblich von der Website am Hauptursprung unterscheidet. Auf einer Nachrichtenseite könnte die Web-App für Kreuzworträtsel beispielsweise absichtlich über https://crosswords.example.com bereitgestellt und als unabhängige PWA installiert und verwendet werden, ohne dass Ressourcen oder Funktionen mit der Hauptwebsite geteilt werden müssen.

Das Schlechte

Wenn Sie nichts davon tun, ist die Verwendung einer Multi-Origin-Architektur beim Erstellen von Progressive Web Apps wahrscheinlich von Nachteil.

Trotzdem werden viele Websites ohne besonderen Grund oder aus „historischen“ Gründen weiterhin so strukturiert. Ein Beispiel ist die Verwendung von Subdomains, um Teile einer Website, die eigentlich zu einem einheitlichen Erlebnis gehören sollten, willkürlich zu trennen.

Die folgenden Muster werden beispielsweise dringend abgeraten:

  • Websitebereiche: Trennung verschiedener Bereiche einer Website auf Subdomains. Auf Nachrichtenseiten ist es nicht ungewöhnlich, dass die Startseite unter https://www.example.com, der Sportbereich unter https://sports.example.com, der Politikbereich unter https://politics.example.com usw. zu finden ist. Bei einer E-Commerce-Website können Sie beispielsweise https://category.example.com für Produktkategorien, https://product.example.com für Produktseiten usw. verwenden.

  • User-Flow: Ein weiterer Ansatz, von dem abgeraten wird, ist die Trennung verschiedener kleinerer Teile der Website, z. B. Seiten für die Anmeldung oder den Kaufvorgang in Subdomains. Beispiel: https://login.example.com und https://checkout.example.com.

Für Fälle, in denen die Migration zu einem einzigen Ursprung nicht möglich ist, finden Sie im Folgenden eine Liste von Herausforderungen und (wo möglich) Problemumgehungen, die beim Erstellen von progressiven Web-Apps berücksichtigt werden können.

Herausforderungen und Behelfslösungen für PWAs mit unterschiedlichen Ursprüngen

Wenn Sie eine Website mit mehreren Ursprüngen erstellen, ist es schwierig, eine einheitliche PWA-Oberfläche bereitzustellen. Das liegt vor allem an der Same-Origin-Policy, die eine Reihe von Einschränkungen mit sich bringt. Sehen wir uns die einzelnen Schritte nacheinander an.

Service Worker

Der Ursprung der URL des Service Worker-Skripts muss mit dem Ursprung der Seite übereinstimmen, die register() aufruft. Das bedeutet, dass beispielsweise eine Seite unter https://www.example.com nicht register() mit einer Service Worker-URL unter https://section.example.com aufrufen kann.

Ein weiterer Aspekt ist, dass ein Service Worker nur Seiten steuern kann, die unter dem Ursprung und Pfad gehostet werden, zu dem er gehört. Das bedeutet, dass ein Service Worker, der unter https://www.example.com gehostet wird, nur URLs von diesem Ursprung steuern kann (gemäß dem im scope-Parameter definierten Pfad). Er steuert jedoch keine Seiten in anderen Subdomains, wie z. B. in https://section.example.com.

In diesem Fall besteht die einzige Problemumgehung darin, mehrere Service Worker zu verwenden (einen pro Ursprung).

Caching

Das Cache-Objekt, indexedDB und localStorage sind ebenfalls auf einen einzelnen Ursprung beschränkt. Das bedeutet, dass es nicht möglich ist, auf die Caches zuzugreifen, die zu https://www.example.com gehören, z. B. von https://www.section.example.com.

Hier sind einige Möglichkeiten, wie Sie Caches in solchen Szenarien richtig verwalten können:

  • Browser-Caching nutzen: Es wird immer empfohlen, die Best Practices für das herkömmliche Browser-Caching zu verwenden. Diese Technik bietet den zusätzlichen Vorteil, dass im Cache gespeicherte Ressourcen ursprungsübergreifend wiederverwendet werden können, was mit dem Cache des Service Workers nicht möglich ist. Best Practices zur Verwendung des HTTP-Cache mit Service Workern finden Sie in diesem Beitrag.

  • Service Worker-Installation einfach halten: Wenn Sie mehrere Service Worker verwalten, sollten Sie vermeiden, dass Nutzer jedes Mal, wenn sie zu einem neuen Ursprung wechseln, hohe Installationskosten zahlen müssen. Mit anderen Worten: Speichern Sie nur Ressourcen im Cache, die unbedingt erforderlich sind.

Berechtigungen

Berechtigungen sind auch auf Ursprünge beschränkt. Das bedeutet, dass eine Berechtigung, die ein Nutzer dem Ursprung https://section.example.com erteilt hat, nicht auf andere Ursprünge wie https://www.example.com übertragen wird.

Da es keine Möglichkeit gibt, Berechtigungen ursprungsübergreifend zu teilen, besteht die einzige Lösung darin, für jede Subdomain, auf der eine bestimmte Funktion (z.B. Standort) erforderlich ist, eine Berechtigung anzufordern. Für Dinge wie Web-Push-Benachrichtigungen können Sie ein Cookie verwenden, um zu verfolgen, ob die Berechtigung vom Nutzer in einer anderen Subdomain akzeptiert wurde, damit sie nicht noch einmal angefordert wird.

Installation

Wenn Sie eine PWA installieren möchten, muss jeder Ursprung ein eigenes Manifest mit einem start_url haben, das relativ zu sich selbst ist. Das bedeutet, dass ein Nutzer, der die Installationsaufforderung für einen bestimmten Ursprung (z. B. https://section.example.com) erhält, die PWA mit einem start_url nicht für einen anderen Ursprung (z. B. https://www.example.com) installieren kann. Mit anderen Worten: Nutzer, die die Installationsaufforderung in einer Subdomain erhalten, können PWAs nur für die Unterseiten installieren, nicht für die Haupt-URL der App.

Außerdem kann es passieren, dass derselbe Nutzer beim Aufrufen der Website mehrere Installationsaufforderungen erhält, wenn jede Subdomain die Installationskriterien erfüllt und den Nutzer auffordert, die PWA zu installieren.

Um dieses Problem zu beheben, können Sie dafür sorgen, dass die Aufforderung nur auf dem Hauptursprung angezeigt wird. Wenn ein Nutzer eine Subdomain besucht, die die Installationskriterien erfüllt, geschieht Folgendes:

  1. Auf das Ereignis beforeinstallprompt warten.
  2. Verhindern, dass die Aufforderung angezeigt wird, indem Sie event.preventDefault() aufrufen.

So wird die Aufforderung nicht in unbeabsichtigten Bereichen der Website angezeigt, während sie beispielsweise auf der Hauptseite (z.B. der Startseite) weiterhin eingeblendet werden kann.

Eigenständiger Modus

Wenn der Nutzer in einem eigenständigen Fenster außerhalb des im Manifest der PWA festgelegten Bereichs navigiert, verhält sich der Browser anders. Das Verhalten hängt von der jeweiligen Browserversion und dem Anbieter ab. In den neuesten Chrome-Versionen wird beispielsweise ein benutzerdefinierter Chrome-Tab geöffnet, wenn ein Nutzer im eigenständigen Modus den Bereich verlässt.

In den meisten Fällen gibt es dafür keine Lösung. Für kleine Teile der Website, die in Subdomains gehostet werden (z. B. Anmelde-Workflows), kann jedoch eine Problemumgehung angewendet werden:

  1. Die neue URL, https://login.example.com, könnte in einem Vollbild-iFrame geöffnet werden.
  2. Sobald die Aufgabe im iFrame abgeschlossen ist (z. B. der Anmeldevorgang), kann postMessage() verwendet werden, um alle resultierenden Informationen vom iFrame an die übergeordnete Seite zurückzugeben.
  3. Als letzten Schritt können die Listener abgemeldet werden, sobald die Nachricht auf der Hauptseite empfangen wurde. Anschließend wird der iFrame aus dem DOM entfernt.

Fazit

Die Same-Origin-Policy schränkt Websites, die auf mehreren Ursprüngen basieren und eine einheitliche PWA-Nutzung bieten möchten, stark ein. Aus diesem Grund empfehlen wir dringend, Websites nicht in verschiedene Ursprünge aufzuteilen, um Nutzern die bestmögliche Erfahrung zu bieten.

Bei bestehenden Websites, die bereits so aufgebaut sind, kann es schwierig sein, PWAs mit mehreren Ursprüngen korrekt zum Laufen zu bringen. Wir haben jedoch einige mögliche Problemumgehungen untersucht. Jede Methode hat Vor- und Nachteile. Entscheiden Sie daher selbst, welchen Ansatz Sie auf Ihrer Website verfolgen möchten.

Wenn Sie eine langfristige Strategie oder eine Neugestaltung Ihrer Website planen, sollten Sie die Migration zu einem einzigen Ursprung in Betracht ziehen, es sei denn, es gibt einen wichtigen Grund, die Architektur mit mehreren Ursprüngen beizubehalten.

Vielen Dank für die technischen Überprüfungen und Vorschläge: Penny Mclachlan, Paul Covell, Dominick Ng, Alberto Medina, Pete LePage, Joe Medley, Cheney Tsai, Martin Schierle und Andre Bandarra.