Service Worker: Header an Anforderungen für CSS- und JS-Dateien anhängen

8

Ich habe versucht, Servicemitarbeiter für (wie es scheint Stunden und Stunden) zu verwenden, um allen Anfragen einen einfachen Header hinzuzufügen. Was frustrierend ist, es funktioniert irgendwie.

Versuch 1:

self.addEventListener("fetch", event => {
   const modifiedHeaders = new Headers({
      ...event.request.headers,
      'API-Key': '000000000000000000001'
   });
   const modifiedRequest = new Request(event.request, {
      headers: modifiedHeaders,
   }); 
   event.respondWith((async () => {
     return fetch(modifiedRequest);
   })());
});

Der obige Code funktioniert für HTML-Dateien, aber für CSS- und JS-Dateien wird der folgende Fehler angezeigt

ReferenceError: Header sind nicht definiert

Wenn ich die Header-Anforderung deaktiviere, wird die Seite mit Bildern und Javascript geladen und ich kann wie gewohnt damit interagieren.

Versuch 2:

var req = new Request(event.request.url, {
   headers: {
     ...event.request.headers,
      'API-Key': '000000000000000000001'
      },
   method: event.request.method,
   mode:  event.request.mode,
   credentials: event.request.credentials,
   redirect: event.request.redirect,
   referrer: event.request.referrer,
   referrerPolicy: event.request.referrerPolicy,
   bodyUsed: event.request.bodyUsed,
   cache: event.request.cache,
   destination: event.request.destination,
   integrity: event.request.integrity,
   isHistoryNavigation: event.request.isHistoryNavigation,
   keepalive:  event.request.keepalive
 });

Bei diesem Versuch habe ich einfach eine neue Anforderung erstellt, die den neuen Header für CSS- und JS-Dateianforderungen erfolgreich enthielt. Wenn ich jedoch einen POST oder eine Umleitung mache, funktionieren die Dinge nicht mehr und verhalten sich seltsam.

Was ist der richtige Ansatz dafür? Ich bin der Meinung, dass Versuch 1 der bessere Pfad ist, aber ich kann das Headers-Objekt auf der Anfrage nicht erstellen, egal was ich tue.

Die Version von Chrom, die ich benutze, ist

Version 78.0.3904.70 (Official Build) (64-Bit)

Die Site ist ein internes Entwicklertool, sodass keine browserübergreifende Kompatibilität erforderlich ist. Daher lade ich gerne zusätzliche Bibliotheken / aktiviere experimentelle Funktionen usw.

Jamie
quelle

Antworten:

1

Das Problem ist, dass Ihre geänderten Anforderungen modedie ursprüngliche Anforderung bei beiden Versuchen wiederverwenden

Bei eingebetteten Ressourcen, bei denen die Anforderung über das Markup initiiert wird (sofern das Attribut crossorigin nicht vorhanden ist), erfolgt die Anforderung in den meisten Fällen im no-corsModus, der nur einen sehr begrenzten Satz einfacher Header zulässt .

no-cors - Verhindert, dass die Methode etwas anderes als HEAD, GET oder POST ist und die Header nichts anderes als einfache Header sind. Wenn ServiceWorker diese Anforderungen abfangen, dürfen sie keine Header hinzufügen oder überschreiben, außer solchen, die einfache Header sind ...

Quelle und weitere Informationen zu den Anforderungsmodi: https://developer.mozilla.org/en-US/docs/Web/API/Request/mode

Einfache Header sind die folgenden: accept(nur einige Werte) accept-language, content-language(nur einige Werte) content-type.

Quelle: https://fetch.spec.whatwg.org/#simple-header :

Lösung:

Sie müssen sicherstellen, dass der Modus nicht auf das no-corsErstellen der geänderten Anforderung eingestellt ist. Sie können entweder corsoder auswählen same-origin, je nachdem, ob Sie Ursprungsübergreifende Anforderungen zulassen möchten. (Der navigateModus ist nur für die Navigation reserviert und es ist nicht möglich, mit diesem Modus eine Anfrage zu erstellen.)

Warum Ihr Code für HTML-Dateien funktioniert hat:

Die Anforderung, die beim Navigieren zu einer neuen Seite ausgegeben wird, verwendet den navigateModus. Chrome erlaubt das Erstellen von Anforderungen in diesem Modus mit dem new Request()Konstruktor nicht, scheint den same-originModus jedoch automatisch stillschweigend zu verwenden , wenn eine vorhandene Anforderung mit dem navigateModus als Parameter an den Konstruktor übergeben wird. Dies bedeutet, dass Ihre erste (HTML-Lade-) modifizierte Anforderung den same-originModus hatte, während die CSS- und JS-Ladeanforderungen den no-corsModus hatten.


Arbeitsbeispiel:

'use strict';

/* Auxiliary function to log info about requests to the console */
function logRequest(message, req) {
  const headersString = [...req.headers].reduce((outputString, val) => `${outputString}\n${val[0]}: ${val[1]}`, 'Headers:');
  console.log(`${message}\nRequest: ${req.url}\nMode: ${req.mode}\n${headersString}\n\n`);
}


self.addEventListener('fetch', (event) => {
  logRequest('Fetch event detected', event.request);

  const modifiedHeaders = new Headers(event.request.headers);
  modifiedHeaders.append('API-Key', '000000000000000000001');

  const modifiedRequestInit = { headers: modifiedHeaders, mode: 'same-origin' };
  const modifiedRequest = new Request(event.request, modifiedRequestInit);

  logRequest('Modified request', modifiedRequest);

  event.respondWith((async () => fetch(modifiedRequest))());
});
Petr Srníček
quelle
-2

Ich würde das versuchen:

self.addEventListener("fetch", event => {
    const modifiedRequest = new Request(event.request, {
        headers: {
            'API-Key': '000000000000000000001'
        },
    }); 
    event.respondWith((async () => {
        return fetch(modifiedRequest);
    })());
});
Stefan Ziegler
quelle
1
Ich hätte meine ursprünglichen Header nicht mehr, anstatt meinen API-Schlüssel anzuhängen. Diese Antwort ist nicht hilfreich.
Jamie
Ich habe es nicht versucht, aber die Dokumentation besagt, dass die Header der Anfrage hinzugefügt werden. Hast du es schon versucht? Ersetzt es die Header aus der ursprünglichen Anforderung oder verwendet dieser Konstruktoraufruf die Header aus der vorherigen Anforderung und fügt die neuen Header hinzu? Der einzige Grund, warum Sie Fehler sehen, ist ein Problem mit den Headern. Haben Sie bereits die Header der endgültigen Anfrage (modifiedRequest) überprüft?
Stefan Ziegler