HTTP-Caching-Verhalten konfigurieren

In diesem Codelab erfahren Sie, wie Sie die HTTP-Caching-Header ändern, die von einem Node.js-basierten Webserver zurückgegeben werden, auf dem das Express-Framework ausgeführt wird. Außerdem wird gezeigt, wie Sie mit dem Netzwerkbereich in den Chrome-DevTools bestätigen können, dass das erwartete Caching-Verhalten tatsächlich angewendet wird.

Beispielprojekt kennenlernen

Dies sind die wichtigsten Dateien, mit denen Sie im Beispielprojekt arbeiten werden:

  • server.js enthält den Node.js-Code, der die Inhalte der Webanwendung bereitstellt. Express wird verwendet, um HTTP-Anfragen und ‑Antworten zu verarbeiten. Insbesondere wird express.static() verwendet, um alle lokalen Dateien im öffentlichen Verzeichnis bereitzustellen. Die Dokumentation zu serve-static ist daher sehr hilfreich.
  • public/index.html ist der HTML-Code der Web-App. Wie die meisten HTML-Dateien enthält sie keine Versionsinformationen als Teil ihrer URL.
  • public/app.15261a07.js und public/style.391484cf.css sind die JavaScript- und CSS-Assets der Webanwendung. Diese Dateien enthalten jeweils einen Hash in ihren URLs, der ihrem Inhalt entspricht. Die index.html ist dafür verantwortlich, welche bestimmte versionierte URL geladen werden soll.

Caching-Header für unser HTML konfigurieren

Wenn Sie auf Anfragen nach URLs antworten, die keine Versionsinformationen enthalten, fügen Sie Ihren Antwortnachrichten Cache-Control: no-cache hinzu. Außerdem wird empfohlen, einen von zwei zusätzlichen Antwortheadern festzulegen: entweder Last-Modified oder ETag. Die index.html fällt in diese Kategorie. Sie können dies in zwei Schritte unterteilen.

Die Überschriften Last-Modified und ETag werden durch die Konfigurationsoptionen etag und lastModified gesteuert. Beide Optionen haben standardmäßig true für alle HTTP-Antworten. In dieser aktuellen Konfiguration müssen Sie also nicht zustimmen, um dieses Verhalten zu erhalten. Sie können die Konfiguration aber trotzdem explizit angeben.

Zweitens müssen Sie den Cache-Control: no-cache-Header hinzufügen können, aber nur für Ihre HTML-Dokumente (in diesem Fall index.html). Am einfachsten lässt sich dieser Header bedingt festlegen, indem Sie ein benutzerdefiniertes setHeaders function schreiben und darin prüfen, ob die eingehende Anfrage für ein HTML-Dokument bestimmt ist.

  • Klicken Sie auf Remix to Edit (Remixen, um zu bearbeiten), damit das Projekt bearbeitet werden kann.

Die statische Bereitstellungskonfiguration in server.js sieht anfangs so aus:

app.use(express.static('public'));
  • Nehmen Sie die oben beschriebenen Änderungen vor. Das Ergebnis sollte so aussehen:
app.use(express.static('public', {
  etag: true, // Just being explicit about the default.
  lastModified: true,  // Just being explicit about the default.
  setHeaders: (res, path) => {
    if (path.endsWith('.html')) {
      // All of the project's HTML files end in .html
      res.setHeader('Cache-Control', 'no-cache');
    }
  },
}));

Caching-Header für die versionierten URLs konfigurieren

Wenn Sie auf Anfragen nach URLs antworten, die Fingerprint oder Versionsinformationen enthalten und deren Inhalt sich nie ändern soll, fügen Sie Ihren Antworten Cache-Control: max-age=31536000 hinzu. Die app.15261a07.js und style.391484cf.css fallen in diese Kategorie.

Aufbauend auf dem setHeaders function aus dem letzten Schritt können Sie zusätzliche Logik hinzufügen, um zu prüfen, ob eine bestimmte Anfrage für eine versionierte URL gilt. Wenn ja, fügen Sie den Header Cache-Control: max-age=31536000 hinzu.

Die zuverlässigste Methode hierfür ist die Verwendung eines regulären Ausdrucks, um zu prüfen, ob das angeforderte Asset einem bestimmten Muster entspricht, das Sie für die Hashes kennen. In diesem Beispielprojekt sind es immer acht Zeichen aus den Ziffern 0–9 und den Kleinbuchstaben a–f (also hexadezimale Zeichen). Das Hash wird immer durch das Zeichen . auf beiden Seiten getrennt.

Ein regulärer Ausdruck, der diesen allgemeinen Regeln entspricht, kann als new RegExp('\\.[0-9a-f]{8}\\.') ausgedrückt werden.

  • Ändern Sie die Funktion setHeaders so:
app.use(express.static('public', {
  etag: true, // Just being explicit about the default.
  lastModified: true,  // Just being explicit about the default.
  setHeaders: (res, path) => {
    const hashRegExp = new RegExp('\\.[0-9a-f]{8}\\.');

    if (path.endsWith('.html')) {
      // All of the project's HTML files end in .html
      res.setHeader('Cache-Control', 'no-cache');
    } else if (hashRegExp.test(path)) {
      // If the RegExp matched, then we have a versioned URL.
      res.setHeader('Cache-Control', 'max-age=31536000');
    }
  },
}));

Neues Verhalten mit den Entwicklertools bestätigen

Nachdem Sie die Änderungen am statischen Dateiserver vorgenommen haben, können Sie prüfen, ob die richtigen Header festgelegt werden. Öffnen Sie dazu die Live-App mit dem Bereich „Netzwerk“ der Entwicklertools.

  • Passen Sie die Spalten an, die im Netzwerkbereich angezeigt werden, um die relevantesten Informationen einzublenden. Klicken Sie dazu mit der rechten Maustaste auf die Spaltenüberschrift:

Das Netzwerk-Panel von DevTools konfigurieren

Die relevanten Spalten sind Name, Status, Cache-Control, ETag und Last-Modified.

  • Aktualisieren Sie die Seite, während die Entwicklertools im Netzwerkbereich geöffnet sind.

Nachdem die Seite geladen wurde, sollten im Bereich „Netzwerk“ Einträge wie die folgenden angezeigt werden:

Spalten im Netzwerkbereich.

Die erste Zeile enthält das HTML-Dokument, zu dem Sie navigiert sind. Sie wird ordnungsgemäß mit Cache-Control: no-cache bereitgestellt. Der HTTP-Antwortstatus für diese Anfrage ist 304. Das bedeutet, dass der Browser wusste, dass er das zwischengespeicherte HTML nicht sofort verwenden sollte. Stattdessen hat er eine HTTP-Anfrage an den Webserver gesendet und anhand der Informationen Last-Modified und ETag geprüft, ob es eine Aktualisierung des HTML gab, das er bereits in seinem Cache hatte. Die HTTP 304-Antwort gibt an, dass kein aktualisiertes HTML vorhanden ist.

Die nächsten beiden Zeilen sind für die versionierten JavaScript- und CSS-Assets. Sie sollten mit Cache-Control: max-age=31536000 bereitgestellt werden und der HTTP-Status für jede ist 200. Aufgrund der verwendeten Konfiguration wird keine tatsächliche Anfrage an den Node.js-Server gesendet. Wenn Sie auf den Eintrag klicken, werden zusätzliche Details angezeigt, einschließlich der Information, dass die Antwort „(from disk cache)“ (aus dem Festplatten-Cache) stammt.

Der Netzwerkantwortstatus ist 200.

Die tatsächlichen Werte für die Spalten „ETag“ und „Last-Modified“ sind nicht so wichtig. Wichtig ist, dass sie festgelegt werden.

Zusammenfassung

Nachdem Sie die Schritte in diesem Codelab durchlaufen haben, wissen Sie, wie Sie die HTTP-Antwortheader in einem Node.js-basierten Webserver mit Express für eine optimale Nutzung des HTTP-Cache konfigurieren. Außerdem finden Sie dort die Schritte, die Sie ausführen müssen, um über das Netzwerk-Panel in den Chrome-Entwicklertools zu bestätigen, dass das erwartete Caching-Verhalten verwendet wird.