In seinem Blogpost zu progressiven Web-Apps auf Websites mit mehreren Ursprüngen hat Demian die Herausforderungen beschrieben, die bei der Entwicklung einer einzelnen progressiven Web-App für Websites mit mehreren Ursprüngen auftreten.
Ein Beispiel für diese Art von Websitearchitektur ist eine E‑Commerce-Website, auf der:
- Die Startseite befindet sich unter
https://www.example.com. - Die Kategorieseiten werden unter
https://category.example.comgehostet. - Die Produktdetailseiten unter
https://product.example.com.
Wie im Artikel beschrieben, werden durch die Same-Origin-Policy mehrere Einschränkungen auferlegt, die das Teilen von Service-Workern, Caches und Berechtigungen über verschiedene Ursprünge hinweg verhindern. Aus diesem Grund empfehlen wir dringend, diese Art der Konfiguration zu vermeiden und, falls Sie bereits Websites auf diese Weise erstellt haben, nach Möglichkeit zu einer Websitearchitektur mit einem einzelnen Ursprung zu migrieren.
In diesem Beitrag sehen wir uns den umgekehrten Fall an: Anstelle einer einzelnen PWA für verschiedene Ursprünge analysieren wir den Fall von Unternehmen, die mehrere PWAs mit demselben Domainnamen bereitstellen und den Nutzer darauf hinweisen möchten, dass diese PWAs zur selben Organisation oder zum selben Dienst gehören.
Wie Sie vielleicht bemerkt haben, verwenden wir verschiedene, aber miteinander verbundene Begriffe wie „Domains“ und „Ursprünge“. Sehen Sie sich zuerst die folgenden Konzepte an.
Technische Begriffe
- Domain:Eine beliebige Folge von Labels gemäß Definition im Domain Name System (DNS).
Beispiel:
comundexample.comsind Domains. - Hostname:Ein DNS-Eintrag, der in mindestens eine IP-Adresse aufgelöst wird. Beispiel:
www.example.comwäre ein Hostname,example.comkönnte ein Hostname sein, wenn er eine IP-Adresse hätte, undcomwürde nie in eine IP-Adresse aufgelöst werden und könnte daher nie ein Hostname sein. - Ursprung:Eine Kombination aus einem Schema, einem Hostnamen und einem optionalen Port. Beispiel:
https://www.example.com:443ist ein Ursprung.
Wie der Name schon sagt, werden durch die Same-Origin-Policy Einschränkungen für Ursprünge festgelegt. Daher werden wir in diesem Artikel hauptsächlich auf diesen Begriff verweisen. Dennoch verwenden wir von Zeit zu Zeit „Domains“ oder „Subdomains“, um die verwendete Technik zu beschreiben, mit der die verschiedenen „Ursprünge“ erstellt werden.
Argumente für mehrere zugehörige PWAs
In einigen Fällen möchten Sie möglicherweise unabhängige Apps erstellen, sie aber trotzdem als zur selben Organisation oder „Marke“ gehörig kennzeichnen. Wenn Sie denselben Domainnamen verwenden, können Sie diese Beziehung herstellen. Beispiel:
- Eine E-Commerce-Website möchte eine eigenständige Funktion erstellen, mit der Verkäufer ihr Inventar verwalten können. Dabei soll deutlich gemacht werden, dass die Funktion zur Hauptwebsite gehört, auf der Nutzer Produkte kaufen.
- Eine Sportnachrichtenseite möchte eine spezielle App für ein großes Sportereignis entwickeln, damit Nutzer Statistiken zu ihren Lieblingswettbewerben über Benachrichtigungen erhalten können. Die App soll als Progressive Web-App installiert werden und Nutzer sollen sie als App des Nachrichtenunternehmens erkennen.
- Ein Unternehmen möchte separate Chat-, E-Mail- und Kalender-Apps entwickeln, die als einzelne Apps funktionieren und mit dem Namen des Unternehmens verknüpft sind.
Separate Ursprünge verwenden
In solchen Fällen empfiehlt es sich, jede konzeptionell unterschiedliche App auf einem eigenen Ursprung zu hosten.
Wenn Sie in allen dieselben Domainnamen verwenden möchten, können Sie das mit Subdomains tun. Ein Unternehmen, das mehrere Internet-Apps oder ‑Dienste anbietet, kann beispielsweise eine E‑Mail-App unter https://mail.example.com und eine Kalender-App unter https://calendar.example.com hosten und gleichzeitig den Hauptdienst seines Unternehmens unter https://www.example.com anbieten. Ein weiteres Beispiel ist eine Sportwebsite, die eine unabhängige App erstellen möchte, die sich ausschließlich einem wichtigen Sportereignis wie einer Fußballmeisterschaft bei https://footballcup.example.com widmet und die Nutzer unabhängig von der Hauptsportwebsite unter https://www.example.com installieren und verwenden können. Dieser Ansatz kann auch für Plattformen nützlich sein, auf denen Kunden unter der Marke des Unternehmens eigene unabhängige Apps erstellen können.
Zum Beispiel eine App, mit der Händler ihre eigenen PWAs unter https://merchant1.example.com, https://merchant2.example.com usw. erstellen können.
Durch die Verwendung verschiedener Ursprünge wird die Isolation zwischen den Apps sichergestellt. Das bedeutet, dass jede von ihnen verschiedene Browserfunktionen unabhängig verwalten kann, darunter:
- Installierbarkeit:Jede App hat ihr eigenes Manifest und bietet eine eigene installierbare Umgebung.
- Speicher:Jede App hat eigene Caches, lokalen Speicher und im Grunde alle Formen von geräteinternem Speicher, ohne sie mit anderen zu teilen.
- Service Worker:Jede App hat einen eigenen Service Worker für die registrierten Bereiche.
- Berechtigungen:Berechtigungen sind auch nach Herkunftsorten begrenzt. So wissen Nutzer genau, für welchen Dienst sie Berechtigungen erteilen, und Funktionen wie Benachrichtigungen werden jeder App richtig zugeordnet.
Ein so hohes Maß an Isolation ist im Anwendungsfall mehrerer unabhängiger PWAs am wünschenswertesten. Wir empfehlen diesen Ansatz daher dringend.
Wenn Apps auf Subdomains lokale Daten miteinander teilen möchten, können sie dies weiterhin über Cookies tun. In komplexeren Szenarien können sie den Speicher über einen Server synchronisieren.
Denselben Ursprung verwenden
Beim zweiten Ansatz werden die verschiedenen PWAs auf demselben Ursprung erstellt. Dazu gehören die folgenden Szenarien:
Nicht überlappende Pfade
Mehrere PWAs oder konzeptionelle „Web-Apps“, die auf demselben Ursprung mit nicht überlappenden Pfaden gehostet werden. Beispiel:
https://example.com/app1/https://example.com/app2/
Überlappende oder verschachtelte Pfade
Mehrere PWAs mit demselben Ursprung, deren Bereiche ineinander verschachtelt sind:
https://example.com/(die „äußere App“)https://example.com/app/(die „innere App“)
Die Service Worker API und das Manifestformat ermöglichen beides, indem Sie den Umfang auf Pfadebene festlegen. In beiden Fällen führt die Verwendung desselben Ursprungs jedoch zu vielen Problemen und Einschränkungen, die darauf zurückzuführen sind, dass der Browser diese nicht vollständig als separate „Apps“ betrachtet. Von diesem Ansatz wird daher abgeraten.
Im nächsten Abschnitt werden diese Herausforderungen genauer analysiert und es wird erläutert, was getan werden kann, wenn die Verwendung separater Ursprünge nicht möglich ist.
Herausforderungen bei mehreren PWAs mit demselben Ursprung
Hier sind einige praktische Probleme, die bei beiden Same-Origin-Ansätzen häufig auftreten:
- Speicher:Cookies, lokaler Speicher und alle Formen des geräteinternen Speichers werden zwischen Apps geteilt. Wenn der Nutzer also beschließt, lokale Daten für eine App zu löschen, werden alle Daten aus der Quelle gelöscht. Dies ist nicht für einzelne Apps möglich. In Chrome und einigen anderen Browsern werden Nutzer aktiv aufgefordert, lokale Daten zu löschen, wenn sie eine der Apps deinstallieren. Dies wirkt sich auch auf Daten für die anderen Apps in der Quelle aus. Ein weiteres Problem ist, dass Apps sich auch ihr Speicherkontingent teilen müssen. Wenn eine der beiden Apps zu viel Speicherplatz belegt, wirkt sich das negativ auf die andere aus.
- Berechtigungen:Browserberechtigungen sind an den Ursprung gebunden. Wenn der Nutzer einer App eine Berechtigung erteilt, gilt diese Berechtigung also gleichzeitig für alle Apps mit diesem Ursprung. Das mag sich gut anhören (nicht mehrmals um eine Berechtigung bitten zu müssen), aber denken Sie daran: Wenn der Nutzer die Berechtigung für eine App blockiert, können die anderen Apps diese Berechtigung nicht anfordern oder diese Funktion nicht verwenden. Browserberechtigungen müssen zwar nur einmal pro Ursprung erteilt werden, Systemberechtigungen hingegen einmal pro App, unabhängig davon, ob mehrere Apps auf denselben Ursprung verweisen.
- Nutzereinstellungen:Einstellungen werden auch pro Herkunft festgelegt. Wenn beispielsweise zwei Apps unterschiedliche Schriftgrößen haben und der Nutzer den Zoom nur in einer der Apps anpassen möchte, um dies zu kompensieren, ist das nicht möglich, ohne die Einstellung auch auf die anderen Apps anzuwenden.
Diese Herausforderungen machen es schwierig, diesen Ansatz zu empfehlen. Wenn Sie jedoch keinen separaten Ursprung (z.B. eine Subdomain) verwenden können, wie im Abschnitt Separate Ursprünge verwenden beschrieben, empfehlen wir dringend, von den beiden Optionen mit demselben Ursprung, die wir vorgestellt haben, nicht überlappende Pfade anstelle von überlappenden und verschachtelten Pfaden zu verwenden.
Wie bereits erwähnt, sind die in diesem Abschnitt beschriebenen Herausforderungen für beide Same-Origin-Ansätze gleich. Im nächsten Abschnitt gehen wir genauer darauf ein, warum die Verwendung von sich überschneidenden und verschachtelten Pfaden die am wenigsten empfohlene Strategie ist.
Zusätzliche Herausforderungen bei sich überschneidenden und verschachtelten Pfaden
Ein weiteres Problem bei der Verwendung von sich überschneidenden und verschachtelten Pfaden (wobei https://example.com/ die äußere App und https://example.com/app/ die innere App ist) besteht darin, dass alle URLs in der inneren App tatsächlich sowohl als Teil der äußeren als auch der inneren App betrachtet werden.
In der Praxis ergeben sich dadurch folgende Probleme:
- Installationswerbung:Wenn der Nutzer die innere App (z. B. in einem Webbrowser) aufruft, während die äußere App bereits auf seinem Gerät installiert ist, werden im Browser keine Banner für die Installationswerbung angezeigt und das BeforeInstallPrompt-Ereignis wird nicht ausgelöst. Der Grund dafür ist, dass der Browser prüft, ob die aktuelle Seite zu einer bereits installierten App gehört, und zu dem Schluss kommt, dass dies der Fall ist. Die Problemumgehung besteht darin, die innere App manuell zu installieren (über die Browsermenüoption „Verknüpfung erstellen“) oder die innere App zuerst zu installieren, bevor die äußere App installiert wird.
- Benachrichtigungen und die Badging API: Wenn die äußere App installiert ist, die innere App jedoch nicht, werden Benachrichtigungen und Badges der inneren App fälschlicherweise der äußeren App zugeordnet (die den nächstgelegenen einschließenden Bereich einer installierten App darstellt). Diese Funktion funktioniert richtig, wenn beide Apps auf dem Gerät des Nutzers installiert sind.
- Link-Erfassung: Die äußere App kann URLs erfassen, die zur inneren App gehören. Das ist besonders wahrscheinlich, wenn die äußere App installiert ist, die innere App jedoch nicht. Ebenso werden Links in der äußeren App, die auf die innere App verweisen, nicht in der inneren App erfasst, da sie als Teil des Bereichs der äußeren App betrachtet werden. Wenn diese Apps auf ChromeOS und Android dem Play Store als Trusted Web Activities hinzugefügt werden, werden alle Links von der äußeren App erfasst. Auch wenn die innere App installiert ist, bietet das Betriebssystem dem Nutzer weiterhin die Möglichkeit, sie in der äußeren App zu öffnen.
Fazit
Wir haben uns verschiedene Möglichkeiten angesehen, wie Entwickler mehrere Progressive Web-Apps erstellen können, die sich auf dieselbe Domain beziehen.
Zusammenfassend lässt sich sagen, dass wir dringend empfehlen, einen anderen Ursprung (z.B. durch die Verwendung von Subdomains) für das Hosting unabhängiger PWAs zu verwenden. Das Hosten auf demselben Ursprung birgt viele Herausforderungen, vor allem, weil der Browser diese nicht vollständig als separate Apps betrachtet.
- Separate Ursprünge: Empfohlen
- Gleicher Ursprung, sich nicht überschneidende Pfade: Nicht empfohlen
- Gleicher Ursprung, sich überschneidende und verschachtelte Pfade: Wird dringend abgeraten
Wenn es nicht möglich ist, verschiedene Ursprünge zu verwenden, ist es dringend zu empfehlen, nicht überlappende Pfade wie https://example.com/app1/ und https://example.com/app2/ zu verwenden, anstatt überlappende oder verschachtelte Pfade wie https://example.com/ (für die äußere App) und https://example.com/app/ (für die innere App).
Weitere Informationen
Vielen Dank für die technischen Prüfungen und Vorschläge: Joe Medley, Dominick Ng, Alan Cutter, Daniel Murphy, Penny McLachlan, Thomas Steiner und Darwin Huang