Jak kontrolujemy buforowanie stron internetowych we wszystkich przeglądarkach?

1552

Nasze badania wykazały, że nie wszystkie przeglądarki przestrzegają dyrektyw bufora HTTP w jednolity sposób.

Ze względów bezpieczeństwa nie chcemy niektóre strony w naszej aplikacji do pamięci podręcznej, kiedykolwiek, przez przeglądarkę internetową. Musi to działać w co najmniej następujących przeglądarkach:

  • Internet Explorer 6+
  • Firefox 1.5+
  • Safari 3+
  • Opera 9+
  • Chrom

Nasze wymagania wynikają z testu bezpieczeństwa. Po wylogowaniu z naszej strony internetowej możesz nacisnąć przycisk Wstecz i przeglądać buforowane strony.

Edward Wilde
źródło
Tylko dla iPada Safari. Czy [to] [1] pomaga? [1]: stackoverflow.com/questions/24524248/…
Bakhshi
Najprostszym jest użycie: max-age = 10. Nie jest to idealne, ponieważ strona będzie buforowana przez 10 sekund. Ale to najmniej dostępne rozwiązanie „spaghetti z nagłówkiem”. Czasami zapewnia to również znaczny wzrost wydajności dynamicznych witryn internetowych, które używają odwrotnych serwerów proxy. (Twój powolny skrypt php będzie wywoływany raz na 10 sekund, a następnie będzie buforowany przez odwrotne proxy. Raz na 10 sekund jest znacznie lepszy niż raz na gościa)
Hello World,
3
Dziękuję za to świetne pytanie. Ze względu na ciekawość, jaka może być sytuacja, która powoduje, że wysyłasz niektóre dane, a nie chcesz, aby odbiornik zapisał je ze „względów bezpieczeństwa” . już je wysłałeś!
Księgowy م
1
@Accountant: w swoim scenariuszu użytkownik się wylogował. Kto może zagwarantować, że następnym człowiekiem na tym User-Agent będzie osoba, która właśnie się wylogowała?
Fabien Haddadi

Odpowiedzi:

2578

Wprowadzenie

Prawidłowy minimalny zestaw nagłówków, który działa na wszystkich wymienionych klientach (i serwerach proxy):

Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0

Jest Cache-Controlto zgodne ze specyfikacją HTTP 1.1 dla klientów i serwerów proxy (i domyślnie wymagane przez niektórych klientów obok Expires). Jest Pragmato zgodne ze specyfikacją HTTP 1.0 dla klientów prehistorycznych. TheExpires to zgodne ze specyfikacjami HTTP 1.0 i 1.1 dla klientów i serwerów proxy. W HTTP 1.1 Cache-Controlma pierwszeństwo przed Expires, więc w końcu dotyczy tylko serwerów proxy HTTP 1.0.

Jeśli nie obchodzi Cię IE6 i jego zepsute buforowanie, gdy wyświetlasz strony tylko przez HTTPS no-store udostępniania , możesz to pominąć Cache-Control: no-cache.

Cache-Control: no-store, must-revalidate
Pragma: no-cache
Expires: 0

Jeśli nie przejmujesz się klientami IE6 ani HTTP 1.0 (HTTP 1.1 został wprowadzony w 1997 r.), Możesz to pominąć Pragma .

Cache-Control: no-store, must-revalidate
Expires: 0

Jeśli nie obchodzą Cię również proxy HTTP 1.0, możesz to pominąć Expires .

Cache-Control: no-store, must-revalidate

Z drugiej strony, jeśli serwer automatycznie zawiera poprawny Datenagłówek, to teoretycznie możesz też pominąć Cache-Controli polegać naExpires tylko na.

Date: Wed, 24 Aug 2016 18:32:02 GMT
Expires: 0

Ale może się to nie powieść, jeśli np. Użytkownik końcowy manipuluje datą systemu operacyjnego, a oprogramowanie klienckie na niej polega.

Inne Cache-Controlparametry, takie jak max-agenieistotne, jeśli Cache-Controlzostaną określone wyżej wymienione parametry. Last-ModifiedNagłówek jak zawarte w większości innych odpowiedzi tutaj jest tylko interesujące, jeśli rzeczywiście chcemy buforować żądanie, dzięki czemu nie trzeba określić go wcale.

Jak to ustawić?

Za pomocą PHP:

header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP 1.1.
header("Pragma: no-cache"); // HTTP 1.0.
header("Expires: 0"); // Proxies.

Za pomocą Java Servlet lub Node.js:

response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setHeader("Expires", "0"); // Proxies.

Korzystanie z ASP.NET-MVC

Response.Cache.SetCacheability(HttpCacheability.NoCache);  // HTTP 1.1.
Response.Cache.AppendCacheExtension("no-store, must-revalidate");
Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0.
Response.AppendHeader("Expires", "0"); // Proxies.

Za pomocą interfejsu API sieci Web ASP.NET:

// `response` is an instance of System.Net.Http.HttpResponseMessage
response.Headers.CacheControl = new CacheControlHeaderValue
{
    NoCache = true,
    NoStore = true,
    MustRevalidate = true
};
response.Headers.Pragma.ParseAdd("no-cache");
// We can't use `response.Content.Headers.Expires` directly
// since it allows only `DateTimeOffset?` values.
response.Content?.Headers.TryAddWithoutValidation("Expires", 0.ToString()); 

Za pomocą ASP.NET:

Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0.
Response.AppendHeader("Expires", "0"); // Proxies.

Korzystanie z ASP.NET Core v3

// using Microsoft.Net.Http.Headers
Response.Headers[HeaderNames.CacheControl] = "no-cache, no-store, must-revalidate";
Response.Headers[HeaderNames.Expires] = "0";
Response.Headers[HeaderNames.Pragma] = "no-cache";

Korzystanie z ASP:

Response.addHeader "Cache-Control", "no-cache, no-store, must-revalidate" ' HTTP 1.1.
Response.addHeader "Pragma", "no-cache" ' HTTP 1.0.
Response.addHeader "Expires", "0" ' Proxies.

Korzystanie z Ruby on Rails lub Python / Flask:

headers["Cache-Control"] = "no-cache, no-store, must-revalidate" # HTTP 1.1.
headers["Pragma"] = "no-cache" # HTTP 1.0.
headers["Expires"] = "0" # Proxies.

Za pomocą Python / Django:

response["Cache-Control"] = "no-cache, no-store, must-revalidate" # HTTP 1.1.
response["Pragma"] = "no-cache" # HTTP 1.0.
response["Expires"] = "0" # Proxies.

Za pomocą Python / Pyramid:

request.response.headerlist.extend(
    (
        ('Cache-Control', 'no-cache, no-store, must-revalidate'),
        ('Pragma', 'no-cache'),
        ('Expires', '0')
    )
)

Za pomocą Go:

responseWriter.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") // HTTP 1.1.
responseWriter.Header().Set("Pragma", "no-cache") // HTTP 1.0.
responseWriter.Header().Set("Expires", "0") // Proxies.

Za pomocą .htaccesspliku Apache :

<IfModule mod_headers.c>
    Header set Cache-Control "no-cache, no-store, must-revalidate"
    Header set Pragma "no-cache"
    Header set Expires 0
</IfModule>

Za pomocą HTML4:

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">

Metatagi HTML a nagłówki odpowiedzi HTTP

Ważne jest, aby wiedzieć, że gdy strona HTML jest obsługiwana przez połączenie HTTP, a nagłówek jest obecny zarówno w nagłówkach odpowiedzi HTTP, jak i <meta http-equiv>znacznikach HTML , wówczas określony w nagłówku odpowiedzi HTTP uzyska pierwszeństwo przed metatagiem HTML. Metatag HTML zostanie użyty tylko wtedy, gdy strona zostanie wyświetlona z lokalnego systemu plików dysku za pośrednictwem file://adresu URL. Zobacz także rozdział 5.2.2 specyfikacji HTML W3 . Zachowaj ostrożność, gdy nie określisz ich programowo, ponieważ serwer WWW może mianowicie zawierać pewne wartości domyślne.

Ogólnie rzecz biorąc, lepiej nie podawać metatagów HTML, aby uniknąć pomyłek przez osoby rozpoczynające i polegać na twardych nagłówkach odpowiedzi HTTP. Co więcej, w szczególności te <meta http-equiv>tagi są nieprawidłowe w HTML5. Tylko http-equivwartości wymienione w specyfikacji HTML5 .

Weryfikacja rzeczywistych nagłówków odpowiedzi HTTP

Aby zweryfikować jedno i drugie, można je zobaczyć / debugować w monitorze ruchu HTTP zestawu narzędzi programistycznych przeglądarki internetowej. Możesz się tam dostać, naciskając klawisz F12 w przeglądarce Chrome / Firefox23 + / IE9 +, a następnie otwierając panel karty „Sieć” lub „Sieć”, a następnie klikając interesujące żądanie HTTP, aby wyświetlić wszystkie szczegóły dotyczące żądania i odpowiedzi HTTP. Poniżej zrzut ekranu jest z Chrome:

Zestaw narzędzi dla programistów Chrome Monitor ruchu HTTP pokazujący nagłówki odpowiedzi HTTP na stackoverflow.com

Chcę również ustawić te nagłówki w plikach do pobrania

Przede wszystkim to pytanie i odpowiedź są skierowane na „strony internetowe” (strony HTML), a nie „pliki do pobrania” (PDF, zip, Excel itp.). Lepiej je buforuj i użyj jakiegoś identyfikatora wersji pliku gdzieś na ścieżce URI lub w zapytaniu, aby wymusić ponowne pobranie zmienionego pliku. Przy stosowaniu tych nagłówków no-cache przy pobieraniu plików, uważaj na błąd IE7 / 8, gdy podajesz pobieranie pliku przez HTTPS zamiast HTTP. Aby uzyskać szczegółowe informacje, zobacz IE nie może pobrać foo.jsf. IE nie mógł otworzyć tej strony internetowej. Żądana witryna jest niedostępna lub nie można jej znaleźć .

BalusC
źródło
16
To nie wydaje się być kompletne. Wypróbowałem to rozwiązanie w IE 8 i stwierdziłem, że przeglądarka załaduje wersję z pamięci podręcznej po naciśnięciu przycisku Wstecz.
Mike Ottum,
16
Prawdopodobnie twoja metodologia testowania była błędna. Może strona była już w pamięci podręcznej? Może nagłówki były niepoprawne / zastąpione? Może patrzyłeś na niewłaściwą prośbę? Itd ..
BalusC
8
W rzeczywistości potwierdzam, że to podejście jest niekompletne i powoduje problemy z IE8, a przynajmniej w niektórych okolicznościach. W szczególności, gdy używasz IE8 do pobierania zasobu przez SSL, IE8 odmówi pobrania zasobu po raz drugi (albo w ogóle, albo po pierwszej próbie, w zależności od użytych nagłówków). Zobacz na przykład blog EricLaw .
haylem
21
Chciałbym dodać, że zasadniczo to robi Bank of America. Jeśli spojrzysz na ich nagłówki odpowiedzi i przełożysz je na aspx, robią to: Response.AppendHeader („Cache-Control”, „no-cache, no-store, must-revalidate”); Response.AppendHeader („Expires”, „Thu, 01 Dec 1994 16:00:00 GMT”); Myślę, że jeśli jest dla nich wystarczająco dobry, to dla mnie jest wystarczająco dobry.
Jan
8
@John: Wygasa nagłówek jest dokładnie wartością przykładową w specyfikacji HTTP 1.0 . Działa, ale nieco niedorzeczne jest przyjęcie dokładnie tego znacznika czasu.
BalusC
244

(hej, wszyscy: proszę nie tylko bezmyślnie kopiuj i wklejaj wszystkie nagłówki, które możesz znaleźć)

Po pierwsze, historia przycisku Wstecz nie jest pamięcią podręczną :

Model świeżości (sekcja 4.2) niekoniecznie dotyczy mechanizmów historycznych. Oznacza to, że mechanizm historii może wyświetlić poprzednią reprezentację, nawet jeśli wygasła.

W starej specyfikacji HTTP sformułowanie było jeszcze mocniejsze, wyraźnie mówiąc przeglądarkom, aby ignorowały dyrektywy pamięci podręcznej dotyczące historii przycisków wstecz.

Cofnij ma cofnąć się w czasie (do czasu, kiedy użytkownik był) zalogowany). Nie przechodzi do poprzednio otwartego adresu URL.

Jednak w praktyce pamięć podręczna może wpływać na przycisk Wstecz w bardzo szczególnych okolicznościach:

  • Strona musi być dostarczona przez HTTPS , w przeciwnym razie pomijanie pamięci podręcznej nie będzie niezawodne. Dodatkowo, jeśli nie używasz HTTPS, twoja strona jest podatna na kradzież logowania na wiele innych sposobów.
  • Musisz wysłać Cache-Control: no-store, must-revalidate(niektóre przeglądarki obserwują, no-storea niektóre obserwują must-revalidate)

Nigdy nie potrzebujesz żadnego z:

  • <meta>z nagłówkami pamięci podręcznej - to w ogóle nie działa. Zupełnie bezużyteczne.
  • post-check/ pre-check- to dyrektywa tylko dla IE, która ma zastosowanie tylko do zasobów buforowanych .
  • Wysyłanie tego samego nagłówka dwa razy lub w kilkunastu częściach. Niektóre fragmenty PHP zastępują poprzednie nagłówki, co powoduje wysłanie tylko ostatniego.

Jeśli chcesz, możesz dodać:

  • no-cachelub max-age=0, co sprawi, że zasób (URL) stanie się „nieaktualny” i będzie wymagał od przeglądarek sprawdzenia na serwerze, czy jest dostępna nowsza wersja (no-store już implikuje to jeszcze silniejsze).
  • Expiresz datą w przeszłości dla klientów HTTP / 1.0 (chociaż w rzeczywistości nie ma obecnie prawdziwych klientów obsługujących tylko HTTP / 1.0).

Bonus: nowy RFC buforujący HTTP .

Kornel
źródło
1
czy będzie to miało jakiś wpływ uboczny na wydajność witryny pod względem czasu ładowania? w jaki sposób no-store, no-cache, must-revalidate wpływa na wydajność?
Raman Ghai
@RamanGhai Wyłączenie pamięci podręcznej ogólnie obniża wydajność (i wszystkie 3 wymienione opcje wyłączają buforowanie). Może to powodować nieskuteczność serwerów CDN i serwerów proxy ISP (np. Powszechnie używanych przez operatorów telefonii komórkowej). Nie zaszkodzi najpierw ładowaniu przez nowego użytkownika (oprócz problemu z serwerem proxy), ale późniejsza nawigacja może być znacznie wolniejsza.
Kornel
@porneL oświadczasz, że musimy wysłać Cache-Control: must-revalidate. Dlaczego nie wysłać, Cache-Control: no-cacheskoro no-cachejuż to sugeruje must-revalidate? w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1
Pacerier
3
@Pacerier związek no-cachez must-revalidatejest prawdziwy dla pamięci podręcznej, ale historia wsteczna nie jest pamięcią podręczną. Przeglądarki, w szczególności jawne, must-revalidatedo kontrolowania zachowania historii .
Kornel
@porneL, Hmm, czy istnieje dodatkowy RFC, który stwierdza, że ​​to pożądane zachowanie?
Pacerier
103

Jak stwierdził @Kornel, nie chcesz dezaktywować pamięci podręcznej, ale dezaktywować bufor historii. Różne przeglądarki mają swoje subtelne sposoby wyłączania bufora historii.

W Chrome (v28.0.1500.95 m) możemy to zrobić tylko przez Cache-Control: no-store.

W FireFox (v23.0.1) każdy z nich będzie działał:

  1. Cache-Control: no-store

  2. Cache-Control: no-cache (tylko https)

  3. Pragma: no-cache (tylko https)

  4. Vary: * (tylko https)

W Operze (v12.15) możemy to zrobić Cache-Control: must-revalidatetylko (tylko https).

W przeglądarce Safari (wersja 5.1.7, 7534.57.2) dowolny z nich będzie działał:

  1. Cache-Control: no-store
    <body onunload=""> w html

  2. Cache-Control: no-store (tylko https)

W IE8 (v8.0.6001.18702IC) każdy z nich będzie działał:

  1. Cache-Control: must-revalidate, max-age=0

  2. Cache-Control: no-cache

  3. Cache-Control: no-store

  4. Cache-Control: must-revalidate
    Expires: 0

  5. Cache-Control: must-revalidate
    Expires: Sat, 12 Oct 1991 05:00:00 GMT

  6. Pragma: no-cache (tylko https)

  7. Vary: * (tylko https)

Połączenie powyższego daje nam to rozwiązanie, które działa w Chrome 28, FireFox 23, IE8, Safari 5.1.7 i Opera 12.15: Cache-Control: no-store, must-revalidate (tylko https)

Pamiętaj, że https jest potrzebne, ponieważ Opera nie dezaktywuje bufora historii dla zwykłych stron http. Jeśli naprawdę nie możesz uzyskać https i jesteś gotowy zignorować Operę, najlepsze, co możesz zrobić, to:

Cache-Control: no-store
<body onunload="">

Poniżej przedstawiono surowe dzienniki moich testów:

HTTP:

  1. Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Niepowodzenie: Opera 12.15
    Sukces: Chrome 28, FireFox 23, IE8, Safari 5.1.7

  2. Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Niepowodzenie: Opera 12.15
    Sukces: Chrome 28, FireFox 23, IE8, Safari 5.1.7

  3. Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    Niepowodzenie: Safari 5.1.7, Opera 12.15
    Sukces: Chrome 28, FireFox 23, IE8

  4. Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    Niepowodzenie: Safari 5.1.7, Opera 12.15
    Sukces: Chrome 28, FireFox 23, IE8

  5. Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Niepowodzenie: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Sukces: IE8

  6. Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Niepowodzenie: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Sukces: IE8

  7. Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Niepowodzenie: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Sukces: IE8

  8. Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Niepowodzenie: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Sukces: IE8

  9. Cache-Control: no-store
    Niepowodzenie: Safari 5.1.7, Opera 12.15
    Sukces: Chrome 28, FireFox 23, IE8

  10. Cache-Control: no-store
    <body onunload="">
    Niepowodzenie: Opera 12.15
    Sukces: Chrome 28, FireFox 23, IE8, Safari 5.1.7

  11. Cache-Control: no-cache
    Niepowodzenie: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Sukces: IE8

  12. Vary: *
    Niepowodzenie: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
    Sukces: brak

  13. Pragma: no-cache
    Niepowodzenie: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
    Sukces: brak

  14. Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Niepowodzenie: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Sukces: IE8

  15. Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Niepowodzenie: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Sukces: IE8

  16. Cache-Control: must-revalidate, max-age=0
    Niepowodzenie: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Sukces: IE8

  17. Cache-Control: must-revalidate
    Expires: 0
    Niepowodzenie: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Sukces: IE8

  18. Cache-Control: must-revalidate
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Niepowodzenie: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Sukces: IE8

  19. Cache-Control: private, must-revalidate, proxy-revalidate, s-maxage=0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Niepowodzenie: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
    Sukces: brak

HTTPS:

  1. Cache-Control: private, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    <body onunload="">
    Niepowodzenie: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
    Sukces: brak

  2. Cache-Control: private, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    <body onunload="">
    Niepowodzenie: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
    Sukces: brak

  3. Vary: *
    Niepowodzenie: Chrome 28, Safari 5.1.7, Opera 12.15
    Sukces: FireFox 23, IE8

  4. Pragma: no-cache
    Niepowodzenie: Chrome 28, Safari 5.1.7, Opera 12.15
    Sukces: FireFox 23, IE8

  5. Cache-Control: no-cache
    Niepowodzenie: Chrome 28, Safari 5.1.7, Opera 12.15
    Sukces: FireFox 23, IE8

  6. Cache-Control: private, no-cache, max-age=0, proxy-revalidate, s-maxage=0
    Niepowodzenie: Chrome 28, Safari 5.1.7, Opera 12.15
    Sukces: FireFox 23, IE8

  7. Cache-Control: private, no-cache, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    Niepowodzenie: Chrome 28, Safari 5.1.7, Opera 12.15
    Sukces: FireFox 23, IE8

  8. Cache-Control: private, no-cache, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    Niepowodzenie: Chrome 28, Safari 5.1.7, Opera 12.15
    Sukces: FireFox 23, IE8

  9. Cache-Control: must-revalidate
    Niepowodzenie: Chrome 28, FireFox 23, IE8, Safari 5.1.7
    Sukces: Opera 12.15

  10. Cache-Control: private, must-revalidate, proxy-revalidate, s-maxage=0
    <body onunload="">
    Niepowodzenie: Chrome 28, FireFox 23, IE8, Safari 5.1.7
    Sukces: Opera 12.15

  11. Cache-Control: must-revalidate, max-age=0
    Niepowodzenie: Chrome 28, FireFox 23, Safari 5.1.7
    Sukces: IE8, Opera 12.15

  12. Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Niepowodzenie: Chrome 28, Safari 5.1.7
    Sukces: FireFox 23, IE8, Opera 12.15

  13. Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Niepowodzenie: Chrome 28, Safari 5.1.7
    Sukces: FireFox 23, IE8, Opera 12.15

  14. Cache-Control: no-store
    Niepowodzenie: Opera 12.15
    Sukces: Chrome 28, FireFox 23, IE8, Safari 5.1.7

  15. Cache-Control: private, no-cache, no-store, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Niepowodzenie: Opera 12.15
    Sukces: Chrome 28, FireFox 23, IE8, Safari 5.1.7

  16. Cache-Control: private, no-cache, no-store, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Niepowodzenie: Opera 12.15
    Sukces: Chrome 28, FireFox 23, IE8, Safari 5.1.7

  17. Cache-Control: private, no-cache
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    Niepowodzenie: Chrome 28, Safari 5.1.7, Opera 12.15
    Sukces: FireFox 23, IE8

  18. Cache-Control: must-revalidate
    Expires: 0
    Niepowodzenie: Chrome 28, FireFox 23, Safari 5.1.7,
    sukces: IE8, Opera 12.15

  19. Cache-Control: must-revalidate
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Niepowodzenie: Chrome 28, FireFox 23, Safari 5.1.7,
    sukces: IE8, Opera 12.15

  20. Cache-Control: private, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    <body onunload="">
    Niepowodzenie: Chrome 28, FireFox 23, Safari 5.1.7,
    sukces: IE8, Opera 12.15

  21. Cache-Control: private, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    <body onunload="">
    Niepowodzenie: Chrome 28, FireFox 23, Safari 5.1.7,
    sukces: IE8, Opera 12.15

  22. Cache-Control: private, must-revalidate
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    Niepowodzenie: Chrome 28, Safari 5.1.7
    Sukces: FireFox 23, IE8, Opera 12.15

  23. Cache-Control: no-store, must-revalidate
    Niepowodzenie: brak
    Sukces: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15

Pacerier
źródło
3
Wiem, że został opublikowany kilka lat temu, ale była to interesująca lektura. Ten problem doprowadza mnie do szału od kilku miesięcy, ciało wydaje się naprawdę wiedzieć, jak radzić sobie z kontrolą pamięci podręcznej. Widziałem kilka osób korzystających z, <body onunload="">ale wydaje się, że jest to sposób na obejście faktycznego problemu. Próbowałem użyć .htaccess i zmodyfikować w ten sposób nagłówki, czy jeśli korzystam z HTTPS, czy powinien on działać w ten sposób? Problem dotyczy głównie safari.
Jordania
4
@Jordan, według dzienników powyżej, jeśli masz HTTPS, to dodawanie załatwi sprawę Cache-Control: no-store. <body onunload="">jest potrzebny tylko wtedy, gdy nie masz HTTPS.
Pacerier
37

Uznałem, że trasa web.config jest przydatna (próbowałem dodać ją do odpowiedzi, ale wydaje się, że nie została zaakceptowana, więc opublikuj tutaj)

<configuration>
<system.webServer>
    <httpProtocol>
        <customHeaders>
            <add name="Cache-Control" value="no-cache, no-store, must-revalidate" />
            <!-- HTTP 1.1. -->
            <add name="Pragma" value="no-cache" />
            <!-- HTTP 1.0. -->
            <add name="Expires" value="0" />
            <!-- Proxies. -->
        </customHeaders>
    </httpProtocol>
</system.webServer>

A oto sposób, w jaki express / node.js robi to samo:

app.use(function(req, res, next) {
    res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
    res.setHeader('Pragma', 'no-cache');
    res.setHeader('Expires', '0');
    next();
});
Joseph Connolly
źródło
W przypadku web.config zmodyfikowałbym tylko trochę, aby zastosować niestandardowe nagłówki tylko do tych skryptów, które, jak wiemy, są ładowane dynamicznie / przy użyciu wymagań. Zakładając, że twoje skrypty znajdują się w folderze klienta: <lokalizacja ścieżki = "klient"> ..... </lokalizacja>
Ibrahim ben Salah
Kto może się zastanawiać, co to web.confjest: Jest to główny plik ustawień i konfiguracji ASP.NETaplikacji internetowej. Jest to dokument XML znajdujący się w katalogu głównym. ( wiki ).
kolejne
27

Odkryłem, że wszystkie odpowiedzi na tej stronie wciąż miały problemy. W szczególności zauważyłem, że żaden z nich nie powstrzyma IE8 przed użyciem wersji strony z pamięci podręcznej, gdy uzyskasz do niej dostęp, naciskając przycisk Wstecz.

Po wielu badaniach i testach odkryłem, że jedyne dwa nagłówki, których naprawdę potrzebowałem, to:

Kontrola pamięci podręcznej: bez sklepu
Zmienna: *

Wyjaśnienie nagłówka Vary można znaleźć na stronie http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.6

W przypadku IE6-8, FF1.5-3.5, Chrome 2-3, Safari 4 i Opera 9-10 nagłówki te spowodowały żądanie strony z serwera po kliknięciu łącza do strony lub umieszczeniu adresu URL bezpośrednio w pasku adresu. To obejmuje około 99% wszystkich używanych przeglądarek od stycznia '10.

W IE6 i Opera 9-10 naciśnięcie przycisku Wstecz nadal powodowało załadowanie wersji buforowanej. We wszystkich testowanych przeze mnie przeglądarkach pobierały nową wersję z serwera. Do tej pory nie znalazłem żadnego zestawu nagłówków, który spowodowałby, że przeglądarki nie zwrócą buforowanych wersji stron po naciśnięciu przycisku Wstecz.

Aktualizacja: Po napisaniu tej odpowiedzi zdałem sobie sprawę, że nasz serwer sieciowy identyfikuje się jako serwer HTTP 1.0. Nagłówki, które wymieniłem, są poprawne, aby odpowiedzi z serwera HTTP 1.0 nie były buforowane przez przeglądarki. W przypadku serwera HTTP 1.1 spójrz na odpowiedź BalusC .

Chris Vasselli
źródło
4
Działa to dla przycisku powrotu IE8 !! Po wypróbowaniu wszystkiego w każdej innej sugestii, dodanie nagłówka „Vary: *” jest najwyraźniej jedyną rzeczą, która może zmusić IE8 do ponownego załadowania strony, gdy użytkownik naciśnie przycisk Wstecz. I to czyni pracę nad HTTP / 1.1 serwerach.
coredumperror
W połączeniu z nagłówkami sugerowanymi przez BarlusC oraz fragmentem kodu JS, który wywołuje funkcję window.location.reload (), gdy zdarzenie onPageShow wyzwala atrybut „utrwalony” (wymagany w przeglądarce Safari), każda przetestowana przeglądarka z powodzeniem wymusza przeładowanie z serwer, gdy użytkownik używa przycisku Wstecz.
coredumperror
1
@CoreDumpError, och, nie powinieneś zakładać, że JavaScript jest włączony.
Pacerier,
@Pacerier Kiedy pisałem odpowiedź w 2010 roku, działało to na najnowszych wersjach zarówno Safari, jak i Opery, a nasz serwer identyfikował się jako serwer HTTP 1.0. Niestety nie mam już sposobu na łatwe przetestowanie tego, więc nie mogę powiedzieć nic ostatecznego o najnowszych wersjach tych przeglądarek.
Chris Vasselli
Z jakimi wersjami przeglądarki testowałeś?
Pacerier
21

Po krótkich badaniach opracowaliśmy następującą listę nagłówków, które zdawały się obejmować większość przeglądarek:

W ASP.NET dodaliśmy je za pomocą następującego fragmentu:

Response.ClearHeaders(); 
Response.AppendHeader("Cache-Control", "no-cache"); //HTTP 1.1
Response.AppendHeader("Cache-Control", "private"); // HTTP 1.1
Response.AppendHeader("Cache-Control", "no-store"); // HTTP 1.1
Response.AppendHeader("Cache-Control", "must-revalidate"); // HTTP 1.1
Response.AppendHeader("Cache-Control", "max-stale=0"); // HTTP 1.1 
Response.AppendHeader("Cache-Control", "post-check=0"); // HTTP 1.1 
Response.AppendHeader("Cache-Control", "pre-check=0"); // HTTP 1.1 
Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0 
Response.AppendHeader("Expires", "Mon, 26 Jul 1997 05:00:00 GMT"); // HTTP 1.0 

Znalezione z: http://forums.asp.net/t/1013531.aspx

Edward Wilde
źródło
36
@bart: Jeszcze bardziej kłopotliwe jest to, że 26 lipca 1997 r. była sobota, a nie poniedziałek ...
C
5
Cache-Control: no-cachei Cache-Control: privatekolizja - nigdy nie powinieneś zbierać razem: pierwsza mówi przeglądarkom i serwerom proxy, aby w ogóle nie buforować, druga informuje proxy, aby nie buforować, ale pozwala przeglądarkom przechowywać ich prywatną kopię. Nie jestem pewien, które ustawienie zostanie zastosowane w przeglądarce, ale jest mało prawdopodobne, aby była spójna między przeglądarkami i wersjami.
Keith,
Nie używaj kontroli wstępnej i późniejszej. blogs.msdn.com/b/ieinternals/archive/2009/07/20/...
EricLaw
to nie działało dla mnie - przy użyciu asp.net 4.5 kod działa, ale nie daje wymaganego rezultatu. Musiałem śledzić to: stackoverflow.com/questions/22443932/...
Andy,
8

Użycie nagłówka pragma w odpowiedzi to opowieść o żonach. RFC2616 definiuje go tylko jako nagłówek żądania

http://www.mnot.net/cache_docs/#PRAGMA

Dave Cheney
źródło
4
To dobry przykład, dlaczego musisz wykraczać poza specyfikacje. Gdyby specyfikacje były zawsze krystalicznie czyste, nie byłoby wiele sensu dla stron takich jak StackOverflow. Od Microsoft W celu zapewnienia kompatybilności wstecznej z serwerami HTTP 1.0, Internet Explorer obsługuje specjalne użycie nagłówka HTTP Pragma: no-cache. Jeśli klient komunikuje się z serwerem za pośrednictwem bezpiecznego połączenia (https: //), a serwer zwraca nagłówek Pragma: no-cache z odpowiedzią, program Internet Explorer nie buforuje odpowiedzi.
michaelok,
@michaelok: Twoje odniesienie jest poprawne, ale brakuje mu większego znaczenia - Ustaw odpowiednią kontrolę pamięci podręcznej / wygasa i nie potrzebujesz pragmy.
EricLaw
8

ZASTRZEŻENIE: Zdecydowanie sugeruję przeczytanie odpowiedzi @ BalusC. Po przeczytaniu następującego samouczka buforowania: http://www.mnot.net/cache_docs/ (polecam też go przeczytać), uważam, że jest poprawny. Jednak ze względów historycznych (i ponieważ sam to przetestowałem) dołączę moją oryginalną odpowiedź poniżej:


Próbowałem „zaakceptowanej” odpowiedzi dla PHP, która nie działała dla mnie. Potem przeprowadziłem małe badania, znalazłem niewielki wariant, przetestowałem go i zadziałało. Oto on:

header('Cache-Control: no-store, private, no-cache, must-revalidate');     // HTTP/1.1
header('Cache-Control: pre-check=0, post-check=0, max-age=0, max-stale = 0', false);  // HTTP/1.1
header('Pragma: public');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');                  // Date in the past  
header('Expires: 0', false); 
header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
header ('Pragma: no-cache');

To powinno działać. Problem polegał na tym, że przy dwukrotnym ustawianiu tej samej części nagłówka, jeśli falsenie jest on wysyłany jako drugi argument do funkcji nagłówka, funkcja nagłówka po prostu zastąpi poprzednie header()wywołanie. Tak więc, ustawiając Cache-Control, na przykład, jeśli nie chce się umieszczać wszystkich argumentów w jednym header()wywołaniu funkcji, musi zrobić coś takiego:

header('Cache-Control: this');
header('Cache-Control: and, this', false);

Zobacz więcej pełnej dokumentacji tutaj .

Steven Oxley
źródło
14
To jest pełne mitów. wstępne i końcowe sprawdzenie są tylko IE, dotyczą tylko buforowanych odpowiedzi, a wartość 0 oznacza brak operacji. max-stale jest nagłówkiem żądania proxy, a nie nagłówkiem odpowiedzi serwera. Wygasa, przyjmuje tylko jedną wartość. Więcej niż jeden spowoduje, że ten nagłówek zostanie zignorowany.
Kornel,
1
@porneL, czy prześlesz konkurencyjną odpowiedź, która prawidłowo zajmuje się tymi mitami?
Dziwne,
@Oddthinking, wygląda na to, że stackoverflow.com/questions/49547/... to konkurencyjna odpowiedź.
Mike Ottum
@Pacerier tak, jak mówię w zrzeczeniu się odpowiedzialności, użyj odpowiedzi BalusC.
Steven Oxley,
8

W przypadku platformy ASP.NET Core utwórz prostą klasę oprogramowania pośredniego:

public class NoCacheMiddleware
{
    private readonly RequestDelegate m_next;

    public NoCacheMiddleware( RequestDelegate next )
    {
        m_next = next;
    }

    public async Task Invoke( HttpContext httpContext )
    {
        httpContext.Response.OnStarting( ( state ) =>
        {
            // ref: http://stackoverflow.com/questions/49547/making-sure-a-web-page-is-not-cached-across-all-browsers
            httpContext.Response.Headers.Append( "Cache-Control", "no-cache, no-store, must-revalidate" );
            httpContext.Response.Headers.Append( "Pragma", "no-cache" );
            httpContext.Response.Headers.Append( "Expires", "0" );
            return Task.FromResult( 0 );
        }, null );

        await m_next.Invoke( httpContext );
    }
}

następnie zarejestruj to w Startup.cs

app.UseMiddleware<NoCacheMiddleware>();

Pamiętaj, aby dodać to gdzieś później

app.UseStaticFiles();
kspearrin
źródło
Sugerowałbym użycie stałych z Microsoft.Net.Http.Headers.HeaderNames zamiast literałów łańcuchowych „Cache-Controls”, „Pragma” i „Expires”.
Victor Sharovatov,
7

Dyrektywy te nie ograniczają żadnego ryzyka bezpieczeństwa. Naprawdę mają one zmusić UA do odświeżania lotnych informacji, a nie powstrzymywać UA przed zatrzymywaniem informacji. Zobacz to podobne pytanie . Przynajmniej nie ma gwarancji, że routery, serwery proxy itp. Również nie zignorują dyrektyw buforowania.

Mówiąc bardziej pozytywnie, zasady dotyczące fizycznego dostępu do komputerów, instalacji oprogramowania i tym podobnych sprawią, że wyprzedzisz większość firm pod względem bezpieczeństwa. Jeśli odbiorcy tych informacji są członkami społeczeństwa, jedyną rzeczą, jaką możesz naprawdę zrobić, to pomóc im zrozumieć, że gdy informacja dotrze do ich maszyny, to ta maszyna jest ich odpowiedzialnością, a nie twoją.

Śmieciarz
źródło
7

W IE6 jest błąd

Treść z „Content-Encoding: gzip” jest zawsze buforowana, nawet jeśli używasz „Cache-Control: no-cache”.

http://support.microsoft.com/kb/321722

Możesz wyłączyć kompresję gzip dla użytkowników IE6 (sprawdź w agencie użytkownika „MSIE 6”)

Edson Medina
źródło
6

RFC dla HTTP 1.1 mówi, że właściwą metodą jest dodanie nagłówka HTTP dla:

Kontrola pamięci podręcznej: brak pamięci podręcznej

Starsze przeglądarki mogą to zignorować, jeśli nie są odpowiednio zgodne z HTTP 1.1. Dla tych możesz wypróbować nagłówek:

Pragma: bez pamięci podręcznej

Ma to również działać w przeglądarkach HTTP 1.1.

Chris Dail
źródło
1
Specyfikacja wskazuje, że odpowiedzi nie można ponownie wykorzystać bez ponownej walidacji. Jest to Cache-Control: no-store, który jest oficjalną metodą wskazującą, że odpowiedź nawet nie jest przechowywana w pamięci podręcznej.
AnthonyWJones
6

Ustawienie zmodyfikowanego nagłówka http na jakąś datę w 1995 r. Zwykle załatwia sprawę.

Oto przykład:

Wygasa: śr., 15 listopada 1995 04:58:08 GMT
Ostatnia modyfikacja: śr., 15 listopada 1995 04:58:08 GMT
Kontrola pamięci podręcznej: bez pamięci podręcznej, należy ponownie sprawdzić
Anders Sandvig
źródło
1
Ustawienie dawno temu Last-Modified nie ma wpływu na buforowanie, poza pozostawieniem buforowanej odpowiedzi na dłuższe użycie z powodu heurystycznej rewalidacji.
EricLaw
6

Dokumentacja PHP dla funkcji nagłówka zawiera dość kompletny przykład (opracowany przez firmę zewnętrzną):

    header('Pragma: public');
    header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");                  // Date in the past   
    header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
    header('Cache-Control: no-store, no-cache, must-revalidate');     // HTTP/1.1
    header('Cache-Control: pre-check=0, post-check=0, max-age=0', false);    // HTTP/1.1
    header ("Pragma: no-cache");
    header("Expires: 0", false);
Szara Pantera
źródło
11
To oczywiście źle. Drugie wywołanie funkcji header () dla Expires, Cache-control i Pragma całkowicie zastępuje wcześniej ustawione wartości.
Kornel,
1
@porneL: Nie, nie zastępuj wcześniej ustawionych wartości, ponieważ przekazuje false jako drugi parametr, mówiąc, aby nie zastępować poprzednich wartości.
Julien Palard
1
@JulienPalard odpowiedź została zredagowana po moim komentarzu. To wciąż nie ma większego sensu.
Kornel
Nie wysyłaj wielu nagłówków Cache-Control, jeśli chcesz pracować w IE przed 9. Nie NIGDY nie wysyłaj kontroli wstępnej ani późniejszej. blogs.msdn.com/b/ieinternals/archive/2009/07/20/…
EricLaw
6

Jeśli masz problemy z pobieraniem IE6-IE8 przez SSL i pamięć podręczną: nagłówek no-cache (i podobne wartości) z plikami MS Office, możesz użyć pamięci podręcznej: private, no-store header and return file on POST. To działa.

Albert
źródło
6

w moim przypadku naprawiam problem chromem

<form id="form1" runat="server" autocomplete="off">

gdzie muszę wyczyścić zawartość poprzednich formularzy danych, gdy użytkownicy klikną przycisk Wstecz ze względów bezpieczeństwa

użytkownik2321638
źródło
Mój problem z przeglądarką Mozilla 19.x został również rozwiązany przez fragment kodu. autocomplete = „off”. Dziękuję Ci.
Satya,
5

Akceptowana odpowiedź nie działa w przypadku IIS7 + ze względu na dużą liczbę pytań o to, że nagłówki pamięci podręcznej nie są wysyłane w II7:

I tak dalej

Przyjęta odpowiedź jest poprawna w tym, które nagłówki muszą być ustawione, ale nie w tym, jak muszą być ustawione. W ten sposób działa z IIS7:

Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.AppendCacheExtension("no-store, must-revalidate");
Response.AppendHeader("Pragma", "no-cache");
Response.AppendHeader("Expires", "-1");

Pierwsza linia Cache-controljest no-cacheustawiona na , a druga linia dodaje inne atrybutyno-store, must-revalidate

JK.
źródło
To działa dla mnie:Response.Cache.SetAllowResponseInBrowserHistory(false); Response.Cache.SetCacheability(HttpCacheability.NoCache); Response.Cache.SetNoStore(); Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
Vilx-
4

Miałem najlepsze i najbardziej spójne wyniki we wszystkich przeglądarkach, ustawiając Pragma: no-cache

petr k.
źródło
4

Nagłówki w odpowiedzi dostarczonej przez BalusC nie uniemożliwiają Safari 5 (i prawdopodobnie także starszym wersjom) wyświetlania zawartości z pamięci podręcznej przeglądarki podczas używania przycisku Wstecz przeglądarki. Aby temu zapobiec, można dodać pusty atrybut procedury obsługi zdarzeń onunload do znacznika body:

<body onunload=""> 

Ten hack najwyraźniej psuje pamięć podręczną do tyłu w Safari: Czy po kliknięciu przycisku Wstecz występuje zdarzenie obciążenia przeglądarki?

Tobiasz
źródło
Fajnie, przetestowałem to i tak naprawdę działa na Safari (5.1.7), ale nie w Operze.
Pacerier
4

Również tylko na wszelki wypadek, upewnij się zresetować ExpiresDefaultw .htaccesspliku, jeśli używasz, że aby włączyć buforowanie.

ExpiresDefault "access plus 0 seconds"

Następnie możesz ExpiresByTypeustawić określone wartości dla plików, które chcesz buforować:

ExpiresByType image/x-icon "access plus 3 month"

Może się to również przydać, jeśli pliki dynamiczne, np. Php itp. Są buforowane przez przeglądarkę i nie możesz zrozumieć, dlaczego. Sprawdzić ExpiresDefault.

Obinwanne Hill
źródło
3

Oprócz nagłówków rozważ wyświetlanie strony za pośrednictwem protokołu https . Wiele przeglądarek domyślnie nie buforuje https.

Złupić
źródło
3
//In .net MVC
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult FareListInfo(long id)
{
}

// In .net webform
<%@ OutputCache NoStore="true" Duration="0" VaryByParam="*" %>
yongfa365
źródło
2

Aby ukończyć BalusC -> ODPOWIEDŹ Jeśli używasz perla, możesz użyć CGI, aby dodać nagłówki HTTP.

Za pomocą Perla:

Use CGI;    
sub set_new_query() {
        binmode STDOUT, ":utf8";
        die if defined $query;
        $query = CGI->new();
        print $query->header(
                        -expires       => 'Sat, 26 Jul 1997 05:00:00 GMT',
                        -Pragma        => 'no-cache',
                        -Cache_Control => join(', ', qw(
                                            private
                                            no-cache
                                            no-store
                                            must-revalidate
                                            max-age=0
                                            pre-check=0
                                            post-check=0 
                                           ))
        );
    }

Za pomocą apache httpd.conf

<FilesMatch "\.(html|htm|js|css|pl)$">
FileETag None
<ifModule mod_headers.c>
Header unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</ifModule>

Uwaga: kiedy próbowałem użyć html META, przeglądarki zignorowały je i zbuforowały stronę.

Carlos Escalera Alonso
źródło
0

Chcę tylko zaznaczyć, że jeśli ktoś chce zapobiec buforowaniu TYLKO zawartości dynamicznej, dodawanie tych dodatkowych nagłówków powinno być programowo.

Edytowałem plik konfiguracyjny mojego projektu, aby dodać nagłówki bez pamięci podręcznej, ale to także wyłączało buforowanie zawartości statycznej, co zwykle nie jest pożądane. Modyfikacja nagłówków odpowiedzi w kodzie zapewnia buforowanie obrazów i plików stylów.

Jest to dość oczywiste, ale wciąż warte wspomnienia.

I kolejna uwaga. Uważaj przy użyciu metody ClearHeaders z klasy HttpResponse. To może dać ci siniaki, jeśli użyjesz go lekkomyślnie. Jak mi to dało.

Po przekierowaniu na zdarzenie ActionFilterAttribute konsekwencje wyczyszczenia wszystkich nagłówków tracą wszystkie dane sesji i dane w magazynie TempData. Bezpieczniej jest przekierowywać z Akcji lub nie usuwać nagłówków podczas przekierowania.

Z drugiej strony odradzam wszystkim korzystanie z metody ClearHeaders. Lepiej jest usunąć nagłówki osobno. Aby poprawnie ustawić nagłówek Cache-Control, używam tego kodu:

filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
filterContext.HttpContext.Response.Cache.AppendCacheExtension("no-store, must-revalidate");
użytkownik3253726
źródło
0

Nie miałem szczęścia z <head><meta>żywiołami. Dodawanie parametrów związanych z pamięcią podręczną HTTP bezpośrednio (poza dokumentem HTML) rzeczywiście działa dla mnie.

Przykładowy kod w Pythonie za pomocą web.headerwywołań web.py. Celowo zredagowałem mój osobisty, nieistotny kod narzędziowy.

    importuj sieć
    import sys
    import NARZĘDZIA OSOBISTE

    myname = "main.py"

    adresy URL = (
        „/”, „main_class”
    )

    main = web.application (adresy URL, globals ())

    render = web.template.render („templates /”, base = „layout”, cache = False)

    klasa main_class (obiekt):
        def GET (self):
            web.header („Cache-control”, „no-cache, no-store, must-revalidate”)
            web.header („Pragma”, „no-cache”)
            web.header („Wygasa”, „0”)
            return render.main_form ()

        def POST (self):
            msg = "POSTed:"
            form = web.input (funkcja = Brak)
            web.header („Cache-control”, „no-cache, no-store, must-revalidate”)
            web.header („Pragma”, „no-cache”)
            web.header („Wygasa”, „0”)
            zwraca render.index_laid_out (powitanie = msg + funkcja.funkcja)

    jeśli __name__ == "__main__":
        nargs = len (sys.argv)
        # Upewnij się, że po nazwie programu python jest wystarczająca liczba argumentów
        jeśli nargs! = 2:
            LOG-AND-DIE ("% s: Błąd wiersza poleceń, nargs =% s, powinno być 2", moja nazwa, nargs)
        # Upewnij się, że numer portu TCP jest numeryczny
        próbować:
            tcp_port = int (sys.argv [1])
        z wyjątkiem wyjątku jako e:
            LOG-AND-DIE („% s: tcp_port = int (% s) nie powiodło się (nie liczba całkowita)”, moja nazwa, sys.argv [1])
        # Wszystko dobrze!
        JUST-LOG ("% s: Uruchamianie na porcie% d", nazwa_myśli, tcp_port)
        web.httpserver.runsimple (main.wsgifunc (), („localhost”, tcp_port))
        main.run ()

Richard Elkins
źródło
Czy to nie jest już wielokrotnie uwzględnione w odpowiedziach, które były na stronie od lat?
Martin Tournoij,
Dyrektywy META działają w przeglądarce Internet Explorer i wersjach Edge 18 i wcześniejszych. Nowoczesne przeglądarki nie obsługują ich. crbug.com/2763
EricLaw
0

Zobacz ten link do studium przypadku dotyczącego buforowania:

http://securityevaluators.com/knowledge/case_studies/caching/

Podsumowanie, zgodnie z tym artykułem, Cache-Control: no-storedziała tylko w Chrome, Firefox i IE. IE akceptuje inne formanty, ale Chrome i Firefox nie. Link jest dobrym przeczytaniem wraz z historią buforowania i dokumentowania dowodu koncepcji.

Paweł
źródło
0

Nie jestem pewien, czy moja odpowiedź brzmi prosto i głupio, a być może była już znana od dawna, ale ponieważ jednym z Twoich celów jest uniemożliwienie komuś korzystania z przycisku Wstecz przeglądarki do przeglądania twoich historycznych stron , możesz:

window.location.replace("https://www.example.com/page-not-to-be-viewed-in-browser-history-back-button.html");

Oczywiście może to nie być możliwe do wdrożenia w całej witrynie, ale przynajmniej w przypadku niektórych krytycznych stron możesz to zrobić. Mam nadzieję że to pomoże.

Antonio Ooi
źródło
-1

możesz użyć bloku lokalizacji do ustawienia pojedynczego pliku zamiast buforowania całej aplikacji w IIS

 <location path="index.html">
    <system.webServer>
      <httpProtocol>
        <customHeaders>
          <add name="Cache-Control" value="no-cache" />
        </customHeaders>
      </httpProtocol>
    </system.webServer>
  </location>
CodeMind
źródło