Konfigurowanie zachowania buforowania HTTP

W tym ćwiczeniu pokazujemy, jak zmienić nagłówki HTTP dotyczące buforowania zwracane przez serwer WWW oparty na Node.js, który korzysta z platformy Express. Dowiesz się też, jak sprawdzić, czy oczekiwane zachowanie buforowania jest rzeczywiście stosowane, korzystając z panelu Sieć w Narzędziach deweloperskich w Chrome.

Zapoznanie się z przykładowym projektem

Oto najważniejsze pliki, z którymi będziesz pracować w przykładowym projekcie:

  • server.js zawiera kod Node.js, który obsługuje treści aplikacji internetowej. Do obsługi żądań HTTP i odpowiedzi używa platformy Express. W szczególności express.static() służy do obsługi wszystkich plików lokalnych w katalogu publicznym, więc dokumentacja serve-static będzie przydatna.
  • public/index.html to kod HTML aplikacji internetowej. Podobnie jak większość plików HTML nie zawiera on w adresie URL żadnych informacji o wersji.
  • public/app.15261a07.js i public/style.391484cf.css to zasoby JavaScript i CSS aplikacji internetowej. Każdy z tych plików zawiera w adresie URL skrót odpowiadający jego zawartości. index.html odpowiada za śledzenie, który adres URL z określoną wersją ma zostać wczytany.

Konfigurowanie nagłówków buforowania dla kodu HTML

Odpowiadając na żądania dotyczące adresów URL, które nie zawierają informacji o obsłudze wersji, pamiętaj o dodaniu do wiadomości odpowiedzi nagłówka Cache-Control: no-cache. Oprócz tego zalecamy ustawienie jednego z 2 dodatkowych nagłówków odpowiedzi: Last-Modified lub ETag. Do tej kategorii należy index.html. Możesz to zrobić w 2 krokach.

Po pierwsze, nagłówki Last-Modified i ETag są kontrolowane przez opcje konfiguracji etag i lastModified. Obie te opcje są domyślnie ustawione na true dla wszystkich odpowiedzi HTTP, więc w tej konfiguracji nie musisz ich włączać, aby uzyskać takie działanie. Możesz jednak jawnie określić to w konfiguracji.

Po drugie, musisz mieć możliwość dodania nagłówka Cache-Control: no-cache, ale tylko w dokumentach HTML (w tym przypadku index.html). Najprostszym sposobem na warunkowe ustawienie tego nagłówka jest napisanie niestandardowego setHeaders function, w którym sprawdzisz, czy przychodzące żądanie dotyczy dokumentu HTML.

Konfiguracja obsługi statycznej w pliku server.js wygląda na początku tak:

app.use(express.static('public'));
  • Wprowadź opisane powyżej zmiany, a powinien powstać kod podobny do tego:
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');
    }
  },
}));

Skonfiguruj nagłówki buforowania dla adresów URL z wersją

W odpowiedziach na żądania dotyczące adresów URL, które zawierają „odcisk cyfrowy” lub informacje o obsłudze wersji i których zawartość nigdy nie powinna się zmieniać, dodaj Cache-Control: max-age=31536000. Do tej kategorii należą app.15261a07.js i style.391484cf.css.

Na podstawie setHeaders function użytego w ostatnim kroku możesz dodać dodatkową logikę, aby sprawdzić, czy dane żądanie dotyczy adresu URL z wersją, a jeśli tak, dodać nagłówek Cache-Control: max-age=31536000.

Najbardziej niezawodnym sposobem jest użycie wyrażenia regularnego, aby sprawdzić, czy żądany zasób pasuje do określonego wzorca, który odpowiada haszom. W przypadku tego przykładowego projektu jest to zawsze 8 znaków z zestawu cyfr 0–9 i małych liter a–f (czyli znaków szesnastkowych). Hasz jest zawsze oddzielony znakiem . po obu stronach.

Wyrażenie regularne, które jest zgodne z tymi ogólnymi regułami, można zapisać jako new RegExp('\\.[0-9a-f]{8}\\.').

  • Zmodyfikuj funkcję setHeaders, aby wyglądała tak:
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');
    }
  },
}));

Potwierdzanie nowego działania za pomocą Narzędzi deweloperskich

Po wprowadzeniu zmian na serwerze plików statycznych możesz sprawdzić, czy ustawione są prawidłowe nagłówki, wyświetlając podgląd działającej aplikacji z otwartym panelem Sieć w Narzędziach deweloperskich.

  • Dostosuj kolumny wyświetlane w panelu Sieć, aby zawierały najbardziej istotne informacje. Aby to zrobić, kliknij prawym przyciskiem myszy nagłówek kolumny:

Konfigurowanie panelu Sieć w Narzędziach deweloperskich.

Kolumny, na które należy zwrócić uwagę, to Name, Status, Cache-Control, ETag i Last-Modified.

  • Gdy Narzędzia deweloperskie są otwarte w panelu Sieć, odśwież stronę.

Po załadowaniu strony w panelu Sieć powinny pojawić się wpisy podobne do tych:

Kolumny panelu Sieć.

Pierwszy wiersz dotyczy dokumentu HTML, do którego nastąpiło przejście. Jest on prawidłowo wyświetlany za pomocą Cache-Control: no-cache. Stan odpowiedzi HTTP na to żądanie to 304. Oznacza to, że przeglądarka wiedziała, że nie należy od razu używać zapisanego w pamięci podręcznej kodu HTML, ale zamiast tego wysłała żądanie HTTP do serwera WWW, używając informacji Last-Modified i ETag, aby sprawdzić, czy kod HTML, który już miała w pamięci podręcznej, został zaktualizowany. Odpowiedź HTTP 304 oznacza, że nie ma zaktualizowanego kodu HTML.

Kolejne 2 wiersze dotyczą zasobów JavaScript i CSS z numerem wersji. Powinny być wyświetlane z Cache-Control: max-age=31536000, a stan HTTP każdego z nich powinien być 200. Z powodu użytej konfiguracji nie jest wysyłane żadne rzeczywiste żądanie do serwera Node.js. Kliknięcie wpisu spowoduje wyświetlenie dodatkowych szczegółów, w tym informacji, że odpowiedź pochodzi „(z pamięci podręcznej na dysku)”.

Stan odpowiedzi sieci: 200.

Rzeczywiste wartości w kolumnach ETag i Last-Modified nie mają większego znaczenia. Ważne jest, aby potwierdzić, że są one ustawiane.

Podsumowanie

Po wykonaniu czynności opisanych w tym ćwiczeniu wiesz już, jak skonfigurować nagłówki odpowiedzi HTTP na serwerze WWW opartym na Node.js przy użyciu Express, aby optymalnie wykorzystać pamięć podręczną HTTP. Znasz też czynności, które musisz wykonać, aby potwierdzić, że używane jest oczekiwane zachowanie buforowania, za pomocą panelu Sieć w Narzędziach deweloperskich w Chrome.