Próbuję wymyślić, jak prawidłowo obsługiwać pamięć podręczną przeglądarki internetowej dla aplikacji jednostronicowych.
Mam dość typowy projekt: kilka plików HTML, JS i CSS implementujących SPA oraz garść danych JSON zużywanych przez SPA. Problemy pojawiają się, gdy chcę przekazać aktualizację: aktualizuję statyczną część witryny i kod, który generuje JSON w tym samym czasie, ale przeglądarki klienckie często mają buforowaną część statyczną, więc stary kod próbuje przetworzyć nowe dane i może (w zależności od dokonanych zmian) napotkać problemy. (W szczególności IE wydaje się bardziej agresywny niż Chrome lub Firefox w kwestii używania JS w pamięci podręcznej bez ponownego sprawdzania poprawności).
Jak najlepiej sobie z tym poradzić?
- Upewnij się, że moje zmiany JSON są zgodne wstecz i zakładam, że pamięci podręczne przeglądarki wygasną w rozsądnym czasie.
- Osadź jakiś numer wersji zarówno w statycznym JS, jak i JSON, a następnie uruchom,
window.location.reload(true);
jeśli się nie zgadzają. - Wymyśl odpowiednią kombinację nagłówków (
must-revalidate
lubno-cache
cokolwiek innego; źródła różnią się w jaki sposób to zrobić), aby zapewnić, że przeglądarki zawsze sprawdzają poprawność wszystkich zasobów przy każdym załadowaniu, nawet jeśli oznacza to kilka dodatkowych podróży w obie strony, aby załadować witrynę. - Mikro zarządzaj moją kontrolą pamięci podręcznej i wygasaj nagłówki, aby zawartość statyczna wygasała, gdy chcę przekazać aktualizację.
- Coś innego?
javascript
web-applications
caching
Josh Kelley
źródło
źródło
Odpowiedzi:
Potrzebujesz rozwiązania pomijania pamięci podręcznej . Rolą pomijania pamięci podręcznej jest:
W projekcie opartym na Grunt często używa się grunt-rev, aby zapewnić, że wszystkie pliki, które wymagają odświeżenia, mają unikalne nazwy, oparte na ich zawartości.
Jeśli upewnisz się, że twoje pliki JSON otrzymają nazwy plików w pamięci podręcznej wraz z odniesieniami do nich w JavaScript, klienci zawsze będą ładować pliki JSON, których oczekuje Javascript.
Zaletą nazewnictwa plików opartych na haszowaniu jest to, że pliki, które nie uległy zmianie, otrzymają te same nazwy plików po pomijaniu pamięci podręcznej, dzięki czemu przeglądarki mogą bezpiecznie używać zawartości pamięci podręcznej, jeśli nie uległy zmianie.
Oczywiście jest to coś, co chcesz zautomatyzować w ramach kompilacji produkcyjnej projektu, więc nie musisz ręcznie śledzić zmiany nazw plików i odniesień.
źródło
Możesz użyć
if-modified-since + last-modified
lubif-none-match + etag
nagłówków wraz z odpowiednimcache-control
nagłówkiem. (Mogą występować błędy przeglądarki , ale w najnowszych przeglądarkach nie można nic zrobić).Jeśli pliki są statyczne, sugeruję użycie
if-modified-since
, ponieważ można to zrobić automatycznie przy dobrze skonfigurowanym serwerze HTTP. Powinien odesłać 304, jeśli plik nie został zmodyfikowany od ostatniego pobrania.Nie sądzę, aby twoje # 1 i # 2 działałyby długoterminowo. # 3 lub # 4 mogą działać. # 3 jest prostszy, ale musisz nauczyć się radzić sobie z tym problemem tylko raz. Więc gdybym był tobą, wypróbowałbym numer 4, ale rozwiązanie może zależeć od przeglądarki używanej przez twoich klientów ... Na przykład IE8 ma problemy z aktualizacją pamięci podręcznej ajax itp.
źródło
Jeśli możesz dołączyć Java Servlet Filter do swojego SPA, oto działające rozwiązanie: CorrectBrowserCacheHandlerFilter.java
Zasadniczo, gdy przeglądarka żąda plików statycznych, serwer przekieruje każde żądanie do tego samego, ale z parametrem zapytania mieszającego (
?v=azErT
na przykład), który zależy od zawartości docelowego pliku statycznego.W ten sposób przeglądarka nigdy nie buforuje plików statycznych zadeklarowanych
index.html
na przykład w twoim (ponieważ zawsze otrzyma a302 Moved Temporarily
), ale buforuje tylko te z wersją skrótu (serwer za nie odpowie200
). Pamięć podręczna przeglądarki będzie efektywnie wykorzystywana w przypadku plików statycznych z wersją skrótu.Uwaga: Jestem autorem
CorrectBrowserCacheHandlerFilter.java
.źródło