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-Dienstframework ausgeführt wird. Außerdem erfahren Sie, wie Sie mithilfe des Bereichs „Netzwerk“ in den Chrome-DevTools prüfen können, ob das erwartete Caching-Verhalten tatsächlich angewendet wird.

Beispielprojekt kennenlernen

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

  • server.js enthält den Node.js-Code, über den die Inhalte der Webanwendung bereitgestellt werden. Es verwendet Express, um HTTP-Anfragen und ‑antworten zu verarbeiten. Insbesondere wird express.static() verwendet, um alle lokalen Dateien im öffentlichen Verzeichnis bereitzustellen. Daher ist die Dokumentation serve-static von Vorteil.
  • public/index.html ist der HTML-Code der Web-App. Wie die meisten HTML-Dateien enthält sie keine Versionsinformationen in der 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, festzuhalten, welche Versions-URL geladen werden soll.

Caching-Header für HTML-Code konfigurieren

Wenn Sie auf Anfragen für URLs antworten, die keine Versionsinformationen enthalten, müssen Sie Cache-Control: no-cache zu Ihren Antwortnachrichten hinzufügen. 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.

Zuerst werden die Last-Modified- und ETag-Überschriften über die Konfigurationsoptionen etag und lastModified gesteuert. Für beide Optionen ist standardmäßig true für alle HTTP-Antworten festgelegt. Bei dieser aktuellen Konfiguration müssen Sie diese Option also nicht aktivieren, um dieses Verhalten zu erhalten. Sie können Ihre Konfiguration aber trotzdem explizit formulieren.

Zweitens müssen Sie den Cache-Control: no-cache-Header einfü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 einen benutzerdefinierten setHeaders function schreiben und darin prüfen, ob die eingehende Anfrage ein HTML-Dokument betrifft.

  • Klicke auf Remix zum Bearbeiten, um das Projekt bearbeitbar zu machen.

Die Konfiguration für die statische Bereitstellung in server.js sieht so aus:

app.use(express.static('public'));
  • Wenn Sie die oben beschriebenen Änderungen vornehmen, sollte das Ergebnis in etwa 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 für URLs antworten, die einen Fingerabdruck oder Versionsinformationen enthalten und deren Inhalt sich nicht ändern soll, fügen Sie Ihren Antworten Cache-Control: max-age=31536000 hinzu. app.15261a07.js und style.391484cf.css gehören in diese Kategorie.

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

Die zuverlässigste Methode ist die Verwendung eines regulären Ausdrucks, um zu prüfen, ob das angeforderte Asset einem bestimmten Muster entspricht, das du kennst und in das die Hashes fallen. In diesem Beispielprojekt sind es immer acht Zeichen aus den Ziffern 0–9 und den Kleinbuchstaben a–f (d.h. hexadezimal). Der Hash ist auf beiden Seiten immer durch das Zeichen . getrennt.

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

  • Ändern Sie die setHeaders-Funktion 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 die Änderungen am statischen Dateiserver vorgenommen wurden, können Sie prüfen, ob die richtigen Header festgelegt werden. Rufen Sie dazu eine Vorschau der Live-Anwendung auf, während der Netzwerkbereich der Entwicklertools geöffnet ist.

  • Wenn Sie sich eine Vorschau der Website ansehen möchten, drücken Sie App ansehen und dann Vollbild Vollbild.

  • Sie können die Spalten, die im Bereich „Netzwerk“ angezeigt werden, anpassen, um die relevantesten Informationen zu sehen. Klicken Sie dazu mit der rechten Maustaste auf die Spaltenüberschrift:

Netzwerkbereich der DevTools konfigurieren

Hier sind die Spalten Name, Status, Cache-Control, ETag und Last-Modified wichtig.

  • Aktualisieren Sie die Seite, während die Entwicklertools im Bereich „Netzwerk“ geöffnet sind.

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

Spalten im Steuerfeld „Netzwerk“.

Die erste Zeile bezieht sich auf das HTML-Dokument, zu dem Sie gewechselt sind. Dieser wird mit Cache-Control: no-cache korrekt gesendet. Der HTTP-Antwortstatus für diese Anfrage ist 304. Das bedeutet, dass der Browser den im Cache gespeicherten HTML-Code nicht sofort verwenden wollte, sondern stattdessen eine HTTP-Anfrage an den Webserver gesendet und dabei die Informationen Last-Modified und ETag verwendet hat, um zu prüfen, ob der HTML-Code bereits im Cache aktualisiert wurde. Die HTTP-304-Antwort gibt an, dass es keine aktualisierte HTML-Datei gibt.

Die nächsten beiden Zeilen beziehen sich auf die JavaScript- und CSS-Assets mit Versionsangabe. Sie sollten mit Cache-Control: max-age=31536000 bereitgestellt werden und der HTTP-Status jeweils 200 lautet. Aufgrund der verwendeten Konfiguration wird keine tatsächliche Anfrage an den Node.js-Server gesendet. Wenn Sie auf den Eintrag klicken, werden weitere Details angezeigt, einschließlich der Information, dass die Antwort „(vom Datenträger-Cache)“ kam.

Netzwerkantwortstatus von 200.

Die tatsächlichen Werte für die Spalten „ETag“ und „Last-Modified“ spielen keine große Rolle. Wichtig ist, dass sie festgelegt werden.

Zusammenfassung

Nachdem Sie die Schritte in diesem Codelab durchgegangen sind, wissen Sie jetzt, wie Sie die HTTP-Antwortheader in einem Node.js-basierten Webserver mit Express konfigurieren, um den HTTP-Cache optimal zu nutzen. Im Bereich „Netzwerk“ in den Chrome-Entwicklertools können Sie auch prüfen, ob das erwartete Caching-Verhalten verwendet wird.