Signatur
Beschreibung
Mit setHeaderValue() legst du fest, welchen Wert der HTTP-Header Service-Worker-Navigation-Preload bei Navigation-Preload-Anfragen hat. Navigation Preload lädt die Navigationsanfrage schon parallel zum Start des Service Workers vom Netzwerk. Deine Seite muss also nicht warten, bis der Worker hochgefahren ist. Die Antwort dieser Vorab-Anfrage bekommst du im fetch-Handler über event.preloadResponse.
Ohne eigenen Wert sendet der Browser standardmäßig Service-Worker-Navigation-Preload: true. Mit einem eigenen Wert kann der Server erkennen, dass es sich um eine Preload-Anfrage handelt, und darauf gezielt anders antworten. Er kann zum Beispiel nur den Inhaltsbereich einer Seite liefern statt des vollständigen HTML-Dokuments, eine Versionskennung auswerten oder einen JSON-Ausschnitt schicken, den der Service Worker dann in eine gecachte Seitenvorlage einfügt.
Die Methode rufst du über registration.navigationPreload auf, meist im activate-Ereignis des Service Workers, zusammen mit enable(). Der Wert wird dauerhaft in der Registrierung gespeichert und bleibt auch bei späteren Starts des Workers erhalten.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $value Pflicht | string | Der neue Header-Wert. Er muss ein gültiger HTTP-Header-Wert sein (ByteString, keine Zeilenumbrüche und keine Zeichen außerhalb von Latin-1). Andere Typen werden in einen String umgewandelt. |
Rückgabewert
undefined erfüllt wird, sobald der Wert gespeichert ist. Es wird mit einem TypeError abgelehnt, wenn der Wert kein gültiger Header-Wert ist, und mit einem InvalidStateError (DOMException), wenn es keinen aktiven Service Worker gibt.Beispiele
Preload im activate-Ereignis aktivieren und Header setzen
// sw.js
self.addEventListener('activate', (event) => {
event.waitUntil((async () => {
if (self.registration.navigationPreload) {
await self.registration.navigationPreload.enable();
// Server erkennt so: nur den Inhaltsbereich liefern
await self.registration.navigationPreload.setHeaderValue('content-only');
}
})());
});
Preload-Antwort im fetch-Handler nutzen
// sw.js
self.addEventListener('fetch', (event) => {
if (event.request.mode !== 'navigate') return;
event.respondWith((async () => {
// Antwort der Vorab-Anfrage (Header: Service-Worker-Navigation-Preload: content-only)
const preloaded = await event.preloadResponse;
if (preloaded) return preloaded;
// Rückfall: normale Netzwerkanfrage
return fetch(event.request);
})());
});
Versionskennung übergeben und Zustand prüfen
// sw.js
const APP_VERSION = 'v42';
self.addEventListener('activate', (event) => {
event.waitUntil((async () => {
const np = self.registration.navigationPreload;
if (!np) return;
await np.enable();
await np.setHeaderValue(`app=${APP_VERSION}`);
const state = await np.getState();
console.log(state);
})());
});
Serverseitige Auswertung (Node.js/Express)
import express from 'express';
const app = express();
app.get('/artikel/:id', (req, res) => {
// Header-Namen sind in Express kleingeschrieben
const preload = req.get('service-worker-navigation-preload');
res.set('Vary', 'Service-Worker-Navigation-Preload');
if (preload === 'content-only') {
return res.send(`<article>Artikel ${req.params.id}</article>`);
}
res.send(`<!doctype html><html><body><article>Artikel ${req.params.id}</article></body></html>`);
});
app.listen(3000);
// Wichtig · Fallstricke
- Vary-Header: Liefert der Server je nach Header-Wert unterschiedliche Inhalte, muss er
Vary: Service-Worker-Navigation-Preloadsenden. Sonst können HTTP-Caches oder CDNs eine Teilantwort als vollständige Seite ausliefern. - Die Methode ist nur im Service-Worker-Kontext bzw. über ein
ServiceWorkerRegistration-Objekt verfügbar und erfordert einen sicheren Kontext (HTTPS oderlocalhost). - Ist Navigation Preload aktiviert, musst du
event.preloadResponseauch auswerten (mindestens mitevent.waitUntil(event.preloadResponse)). Sonst wird die Anfrage umsonst gesendet, und manche Browser geben eine Warnung aus. - Ungültige Werte, zum Beispiel mit Zeilenumbrüchen oder Nicht-Latin-1-Zeichen, führen zu einem abgelehnten Promise mit
TypeError. - Browser-Kompatibilität: In Firefox erst ab Version 99, in Safari ab 15.4. Prüfe die Unterstützung vorher mit
if (self.registration.navigationPreload). - Der Header wird nur bei Navigation-Preload-Anfragen gesendet, nicht bei normalen
fetch()-Aufrufen aus dem Worker.