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 DevTools von Chrome 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 serve-static-Dokumentation hilfreich.
  • 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 du auf Anfragen für URLs antwortest, die keine Informationen zur Versionierung enthalten, musst du deinen Antwortnachrichten Cache-Control: no-cache hinzufügen. Außerdem wird empfohlen, einen der beiden zusätzlichen Antwortheader festzulegen: Last-Modified oder ETag. Die index.html fällt in diese Kategorie. Sie können dies in zwei Schritte unterteilen.

Die Last-Modified- und ETag-Überschriften werden zuerst ü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 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 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 Hashwert ist immer auf beiden Seiten durch ein .-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 mithilfe der DevTools bestätigen

Nachdem Sie die Änderungen am Static File Server vorgenommen haben, können Sie prüfen, ob die richtigen Header festgelegt werden. Öffnen Sie dazu die Live-App mit geöffnetem DevTools-Netzwerkbereich und sehen Sie sich die Vorschau an.

  • 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 Netzwerkbereich geöffnet sind.

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

Spalten im Netzwerkbereich

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 wusste, dass er die im Cache gespeicherte HTML-Datei nicht sofort verwenden sollte, sondern stattdessen eine HTTP-Anfrage an den Webserver stellte. Dabei wurden die Informationen Last-Modified und ETag verwendet, um zu prüfen, ob es eine Aktualisierung der HTML-Datei gab, die bereits im Cache gespeichert war. Die HTTP-304-Antwort gibt an, dass es keine aktualisierte HTML-Datei gibt.

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 Seite sollte 200 sein. Aufgrund der verwendeten Konfiguration wird keine Anfrage an den Node.js-Server gesendet. Wenn Sie auf den Eintrag klicken, werden weitere Details angezeigt, darunter, dass die Antwort „(aus dem Festplattencache)“ stammt.

Einen 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 ausgeführt haben, wissen Sie, 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.