Co to jest Cache-Control: private?

148

Kiedy odwiedzam chesseng.herokuapp.com , otrzymuję nagłówek odpowiedzi, który wygląda jak

Cache-Control:private
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/css
Date:Tue, 16 Oct 2012 06:37:53 GMT
Last-Modified:Tue, 16 Oct 2012 03:13:38 GMT
Status:200 OK
transfer-encoding:chunked
Vary:Accept-Encoding
X-Rack-Cache:miss

a potem odświeżam stronę i otrzymuję

Cache-Control:private
Connection:keep-alive
Date:Tue, 16 Oct 2012 06:20:49 GMT
Status:304 Not Modified
X-Rack-Cache:miss

więc wygląda na to, że buforowanie działa. Jeśli to działa w przypadku buforowania, to jaki jest cel Expires i Cache-Control: max-age . Aby wprowadzić w błąd, gdy testuję stronę pod adresem https://developers.google.com/speed/pagespeed/insights/ , wyświetla mi się komunikat „Wykorzystaj pamięć podręczną przeglądarki”.

user782220
źródło
sprawdź ten diagram stackoverflow.com/a/49925190/3748498
pravdomil

Odpowiedzi:

74

Aby odpowiedzieć na pytanie, dlaczego działa buforowanie, mimo że serwer WWW nie zawierał nagłówków:

  • Wygasa: [a date]
  • Cache-Control: max-age =[seconds]

Serwer uprzejmie poprosił pośredników proxy, aby nie buforowali zawartości (tj. Element powinien być przechowywany tylko w prywatnej pamięci podręcznej, tj. Tylko na własnym komputerze lokalnym):

  • Cache-Control: prywatne

Ale serwer zapomniał dołączyć jakichkolwiek wskazówek dotyczących buforowania:

  • zapomnieli dołączyć Expires , więc przeglądarka wie, że będzie używać kopii z pamięci podręcznej do tej daty
  • zapomnieli uwzględnić Max-Age , więc przeglądarka wie, jak długo buforowany element jest dobry
  • zapomnieli dołączyć E-Tag , więc przeglądarka może wykonać warunkowe żądanie

Ale w odpowiedzi zawarli datę ostatniej modyfikacji :

Last-Modified: Tue, 16 Oct 2012 03:13:38 GMT

Ponieważ przeglądarka zna datę modyfikacji pliku, może wykonać żądanie warunkowe . Poprosi serwer o plik, ale poinstruuje serwer, aby wysłał plik tylko wtedy, gdy był modyfikowany od 2012/10/16 3:13:38:

GET / HTTP/1.1
If-Modified-Since: Tue, 16 Oct 2012 03:13:38 GMT

Serwer odbiera żądanie, zdaje sobie sprawę, że klient ma już najnowszą wersję. Zamiast wysyłać klienta 200 OK, a następnie zawartość strony, zamiast tego mówi ci, że twoja buforowana wersja jest dobra:

304 Not Modified

Twoja przeglądarka musiała cierpieć z powodu opóźnienia w wysłaniu żądania do serwera i czekać na odpowiedź, ale zaoszczędziła konieczności ponownego pobierania statycznej zawartości.

Dlaczego Max-Age ? Dlaczego wygasa ?

Ponieważ Last-Modified jest do bani.

Nie wszystko na serwerze ma przypisaną datę. Jeśli tworzę stronę w locie, nie ma z tym żadnej daty - jest teraz . Ale jestem całkowicie skłonny pozwolić użytkownikowi buforować stronę główną przez 15 sekund:

200 OK
Cache-Control: max-age=15

Jeśli użytkownik uderzy F5, będzie nadal pobierał wersję z pamięci podręcznej przez 15 sekund. Jeśli jest to korporacyjny serwer proxy, wszyscy 67198 użytkowników trafiających na tę samą stronę w tym samym 15-sekundowym oknie otrzymają tę samą zawartość - wszystko obsługiwane z zamkniętej pamięci podręcznej. Wydajność wygrywa dla każdego.

Zaletą dodawania Cache-Control: max-agejest to, że przeglądarka nie musi nawet wykonywać warunkowego żądania.

  • jeśli podałeś tylko Last-Modified, przeglądarka musi wykonać żądanie If-Modified-Sincei czekać na 304 Not Modifiedodpowiedź
  • jeśli to określiłeś max-age, przeglądarka nie będzie musiała nawet cierpieć w obie strony sieci; zawartość wyjdzie prosto z pamięci podręcznych

Różnica między „Cache-Control: max-age” a „Expires”

Expiresjest starszym odpowiednikiem nowoczesnego (ok. 1998) Cache-Control: max-agenagłówka:

  • Expires: określasz datę (fuj)
  • max-age: określasz sekundy (dobroć)
  • Jeśli oba są określone, przeglądarka używa max-age:

    200 OK
    Cache-Control: max-age=60
    Expires: 20180403T192837 
    

Żadna witryna internetowa napisana po 1998 roku nie powinna Expiresjuż używać , a zamiast tego używać max-age.

Co to jest ETag?

ETag jest podobny do Last-Modified , z tym wyjątkiem, że nie musi to być data - po prostu musi być czymś .

Jeśli rowversionwyciągam listę produktów z bazy danych, serwer może wysłać ostatni jako ETag, a nie datę:

200 OK
ETag: "247986"

Mój ETag może być hashem SHA1 zasobu statycznego (np. Obraz, js, css, czcionka) lub strony wyrenderowanej w pamięci podręcznej (tj. To właśnie robi wiki Mozilla MDN; haszuje ostateczny znacznik):

200 OK
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

I dokładnie tak, jak w przypadku żądania warunkowego opartego na Last-Modified :

GET / HTTP/1.1
If-Modified-Since: Tue, 16 Oct 2012 03:13:38 GMT

304 Not Modified

Mogę wykonać warunkowe żądanie na podstawie ETag:

GET / HTTP/1.1
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

304 Not Modified

An ETagjest lepszy od, Last-Modifiedponieważ działa w przypadku rzeczy innych niż pliki lub rzeczy, które mają pojęcie daty . Po prostu jest

Ian Boyd
źródło
1
Niesamowite! Za tę odpowiedź wyznaczyłem nagrodę. Co się stanie, jeśli cache-controlnie istnieje? Masz tylko Etag? Czy nadal nie trzeba wysyłać „warunkowego żądania” do serwera? Zachowanie, które widzę, gdy jestem offline, polega na tym, że po prostu wraca z pamięci podręcznej. Ale gdy jest offline, nie może wysłać tego warunkowego żądania. Czy to oznacza, że ​​będzie buforować na czas nieokreślony, jeśli pozostaniesz w trybie offline? Już tutaj szczegółowo zadałem to pytanie . Możesz spojrzeć?
Miód
167
Cache-Control: private

Wskazuje, że całość lub część komunikatu odpowiedzi jest przeznaczona dla pojedynczego użytkownika i NIE MOŻE być zapisywana w pamięci podręcznej współużytkowanej, takiej jak serwer proxy.

Z RFC2616 sekcja 14.9.1

Dan D.
źródło
14
Ponieważ został zapisany w pamięci podręcznej przeglądarki. Jesteś jedynym użytkownikiem, dla którego była przeznaczona odpowiedź.
Dan D.,
13
Nie, to nie dlatego, że Cache-Control:privatetylko stwierdza, że ​​współużytkowane pamięci podręczne (takie jak pamięci podręczne proxy) nie powinny buforować odpowiedzi.
Dan D.,
5
@Trejkaz Nie, to naprawdę oznacza jednego użytkownika. Użytkownik to konto, które ma własny katalog domowy, w którym znajduje się pamięć podręczna. Profile, które są własnością tego samego użytkownika, mogą współdzielić pamięć podręczną. Jak znalazłeś. Jednak dwa profile na tym samym komputerze, jeśli należą do różnych użytkowników, nie mogą współużytkować pamięci podręcznej, chyba że ta pamięć podręczna jest traktowana jako współużytkowana pamięć podręczna.
Dan D.,
2
Ach, więc to jest na użytkownika na poziomie systemu operacyjnego. Tak, powodem, dla którego się zastanawiam, jest wyraźny wyciek informacji między oknami incognito w Chrome a oknami nieobsługiwanymi, które wykorzystują do tego pamięć podręczną.
Trejkaz,
2
@didibus proxy-revalidatewymaga, aby serwery proxy zawsze weryfikowały poprawność przy każdym dostępie. Gdzie as privatezapobiega buforowaniu serwera proxy.
Dan D.,
20

RFC 2616, sekcja 14.9.1 :

Wskazuje, że całość lub część komunikatu odpowiedzi jest przeznaczona dla pojedynczego użytkownika i NIE MOŻE być zapisywana w pamięci podręcznej współużytkowanej ... Prywatna (nieudostępniona) pamięć podręczna MOŻE buforować odpowiedź.


Przeglądarki mogą wykorzystać te informacje. Oczywiście aktualny „użytkownik” może oznaczać wiele rzeczy: użytkownika systemu operacyjnego, użytkownika przeglądarki (np. Profile Chrome), itp. Nie jest określony.

Dla mnie bardziej konkretny przykład na Cache-Control: privateto, że serwery proxy (które zazwyczaj mają wielu użytkowników) nie będzie buforować go. Jest przeznaczony dla użytkownika końcowego i nikogo innego.


FYI, RFC wyjaśnia, że ​​nie zapewnia to bezpieczeństwa. Chodzi o to, aby wyświetlać prawidłowe treści, a nie zabezpieczać treści.

To użycie słowa „tylko prywatny” określa, gdzie odpowiedź może być buforowana i nie może zapewnić prywatności treści wiadomości.

Paul Draper
źródło
5
Prywatna (niewspółdzielona) pamięć podręczna MOŻE buforować odpowiedzi. Ta część jest kluczowa. Dzięki.
Oliver
0

Pole nagłówka encji Expires podaje datę / godzinę, po której odpowiedź jest uważana za przestarzałą. Pole Cache-control: maxage podaje wartość wieku (w sekundach) większą niż odpowiedź uważana za nieaktualną.

Mimo że powyższe pole nagłówka daje klientowi mechanizm decydujący o tym, czy wysłać żądanie do serwera. W pewnych warunkach klient wysyła żądanie do serwera, a wartość wieku odpowiedzi jest większa niż wartość maksymalna, dawka oznacza, że ​​serwer musi wysłać zasób do klienta? Może zasoby nigdy się nie zmieniły.

Aby rozwiązać ten problem, HTTP1.1 podaje ostatnio zmodyfikowaną nagłówek. Serwer przekazuje klientowi datę ostatniej modyfikacji odpowiedzi. Gdy klient potrzebuje tego zasobu, wyśle ​​pole nagłówka If-Modified-Since do serwera. Jeśli ta data przypada przed datą modyfikacji zasobu, serwer wyśle ​​zasób do klienta i przekaże kod 200, w przeciwnym razie zwróci klientowi kod 304, co oznacza, że ​​klient może korzystać z zasobu, który buforował.

Lin.Yang
źródło