Achten Sie darauf, dass Ihr Service Worker weiß, was er tun soll, wenn eine teilweise Antwort angefordert wird.
Einige HTTP-Anfragen enthalten einen Range:
-Header, der angibt, dass nur ein Teil der vollständigen Ressource zurückgegeben werden soll. Sie werden häufig zum Streamen von Audio- oder Videoinhalten verwendet, um kleinere Medienblöcke auf Abruf zu laden, anstatt die gesamte Remotedatei auf einmal anzufordern.
Ein Service Worker ist JavaScript-Code, der zwischen Ihrer Webanwendung und dem Netzwerk liegt und möglicherweise ausgehende Netzwerkanfragen abfängt und Antworten darauf generiert.
Bisher funktionierten Bereichsanfragen und Service Worker nicht gut zusammen. Es waren spezielle Maßnahmen erforderlich, um negative Auswirkungen auf Ihren Service Worker zu vermeiden. Glücklicherweise ändert sich das langsam. In Browsern, die das richtige Verhalten zeigen, funktionieren Bereichsanfragen einfach, wenn sie einen Service Worker passieren.
Worin liegt das Problem?
Angenommen, Sie haben einen Service Worker mit dem folgenden fetch
-Ereignislistener, der jede eingehende Anfrage an das Netzwerk weiterleitet:
self.addEventListener('fetch', (event) => {
// The Range: header will not pass through in
// browsers that behave incorrectly.
event.respondWith(fetch(event.request));
});
In Browsern mit dem falschen Verhalten wird der Range:
-Header, der in event.request
enthalten ist, stillschweigend gelöscht. Die vom Remote-Server empfangene Anfrage enthält Range:
nicht. Dies würde nicht unbedingt zu Problemen führen, da ein Server technisch berechtigt ist, den vollständigen Antworttext mit einem 200
-Statuscode zurückzugeben, auch wenn in der ursprünglichen Anfrage ein Range:
-Header vorhanden ist. Dies würde jedoch dazu führen, dass mehr Daten übertragen werden, als aus Sicht des Browsers unbedingt erforderlich sind.
Entwickler, die sich dieses Verhaltens bewusst waren, konnten es umgehen, indem sie explizit nach einem Range:
-Header suchten und event.respondWith()
nicht aufriefen, wenn einer vorhanden war. Dadurch entfernt sich der Service Worker effektiv aus dem Bild der Antwortgenerierung und stattdessen wird die Standardnetzwerklogik des Browsers verwendet, die weiß, wie Bereichsanfragen beibehalten werden.
self.addEventListener('fetch', (event) => {
// Return without calling event.respondWith()
// if this is a range request.
if (event.request.headers.has('range')) {
return;
}
event.respondWith(fetch(event.request));
});
Die meisten Entwickler waren sich jedoch nicht bewusst, dass dies erforderlich ist. Außerdem war nicht klar, warum das erforderlich sein sollte. Diese Einschränkung war letztendlich darauf zurückzuführen, dass Browser die Änderungen an der zugrunde liegenden Spezifikation nachholen mussten, durch die diese Funktion unterstützt wurde.
Welche Fehler wurden behoben?
Bei ordnungsgemäß funktionierenden Browsern wird der Range:
-Header beibehalten, wenn event.request
an fetch()
übergeben wird. Das bedeutet, dass der Dienstworker-Code in meinem ersten Beispiel dem Remote-Server den Range:
-Header anzeigt, wenn er vom Browser festgelegt wurde:
self.addEventListener('fetch', (event) => {
// The Range: header will pass through in browsers
// that behave correctly.
event.respondWith(fetch(event.request));
});
Der Server kann jetzt die Anfrage für den Bereich richtig verarbeiten und eine Teilantwort mit dem Statuscode 206
zurückgeben.
Bei welchen Browsern funktioniert das korrekt?
In den neuesten Versionen von Safari ist die Funktion korrekt. Chrome und Edge ab Version 87 funktionieren ebenfalls ordnungsgemäß.
Stand Oktober 2020 wurde dieses Problem in Firefox noch nicht behoben. Daher müssen Sie es möglicherweise berücksichtigen, wenn Sie den Code Ihres Dienstarbeiters in der Produktion bereitstellen.
Am besten sehen Sie im Dashboard für Webplattformtests in der Zeile „Bereichsheader in Netzwerkanfrage einschließen“ nach, ob dieses Verhalten bei einem bestimmten Browser korrigiert wurde.
Wie sieht es mit dem Bereitstellen von Bereichsanfragen aus dem Cache aus?
Dienstprogramme können viel mehr tun, als nur eine Anfrage an das Netzwerk weiterzuleiten. Ein häufiger Anwendungsfall ist das Hinzufügen von Ressourcen wie Audio- und Videodateien zu einem lokalen Cache. Ein Service Worker kann dann Anfragen aus diesem Cache bearbeiten, ohne das Netzwerk zu nutzen.
Alle Browser, einschließlich Firefox, unterstützen die Prüfung einer Anfrage in einem fetch
-Handler, die Prüfung auf Vorhandensein des Range:
-Headers und die lokale Ausführung der Anfrage mit einer 206
-Antwort aus einem Cache. Der Service Worker-Code zum korrekten Parsen des Range:
-Headers und zum Zurückgeben nur des entsprechenden Segments der vollständigen im Cache gespeicherten Antwort ist jedoch nicht trivial.
Glücklicherweise können Entwickler, die Hilfe benötigen, auf Workbox zurückgreifen. Dabei handelt es sich um eine Reihe von Bibliotheken, die gängige Anwendungsfälle für Service Worker vereinfachen. Die workbox-range-request module
implementiert die gesamte Logik, die zum Bereitstellen von Teilantworten direkt aus dem Cache erforderlich ist. Eine vollständige Anleitung für diesen Anwendungsfall finden Sie in der Workbox-Dokumentation.
Das Hero-Image in diesem Beitrag stammt von Natalie Rhea Riggs auf Unsplash.