Wyłączanie pamięci podręcznej przeglądarki dla wszystkich przeglądarek z poziomu ASP.NET

87

Jestem za ostatecznym odniesieniem do tego, jaki kod ASP.NET jest wymagany, aby wyłączyć buforowanie strony przez przeglądarki. Istnieje wiele sposobów wpływania na nagłówki HTTP i metatagi i wydaje mi się, że różne ustawienia są wymagane, aby różne przeglądarki działały poprawnie. Byłoby naprawdę wspaniale, gdybyśmy skomentowali fragment kodu odniesienia, aby wskazać, który działa dla wszystkich przeglądarek, a który jest wymagany dla określonej przeglądarki, w tym wersji.

Jest tam mnóstwo informacji na temat tego problemu, ale nie znalazłem jeszcze dobrego odniesienia opisującego zalety każdej metody i czy dana technika została zastąpiona przez API wyższego poziomu.

Szczególnie interesuje mnie ASP.NET 3.5 SP1, ale dobrze byłoby uzyskać odpowiedzi również na wcześniejszą wersję.

W tym wpisie na blogu Dwie ważne różnice między przeglądarką Firefox a buforowaniem przeglądarki IE opisano niektóre różnice w zachowaniu protokołu HTTP.

Poniższy przykładowy kod ilustruje rodzaj rzeczy, które mnie interesują

public abstract class NoCacheBasePage : System.Web.UI.Page
{
    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);

        DisableClientCaching();
    }

    private void DisableClientCaching()
    {
        // Do any of these result in META tags e.g. <META HTTP-EQUIV="Expire" CONTENT="-1">
        // HTTP Headers or both?

        // Does this only work for IE?
        Response.Cache.SetCacheability(HttpCacheability.NoCache);

        // Is this required for FireFox? Would be good to do this without magic strings.
        // Won't it overwrite the previous setting
        Response.Headers.Add("Cache-Control", "no-cache, no-store");

        // Why is it necessary to explicitly call SetExpires. Presume it is still better than calling
        // Response.Headers.Add( directly
        Response.Cache.SetExpires(DateTime.UtcNow.AddYears(-1));
    }
}
Martin Hollingsworth
źródło
5
Spróbowałbym odpowiedzieć, gdybym nie wiedział, jak okropnie niemożliwe jest twoje zadanie. Kontrolowanie pamięci podręcznej klienta przypomina próbę przestawienia mebli za pomocą pałeczek o długości 10 stóp.
Jeff Meatball Yang
Wiele odpowiedzi, które obejmują tylko część problemu, nadal byłoby bardzo cennych. Dorzuć proszę swoje 2 centy.
Martin Hollingsworth

Odpowiedzi:

96

Oto, czego używamy w ASP.NET:

// Stop Caching in IE
Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);

// Stop Caching in Firefox
Response.Cache.SetNoStore();

Przestaje buforować w przeglądarce Firefox i IE, ale nie próbowaliśmy innych przeglądarek. Następujące nagłówki odpowiedzi są dodawane przez te instrukcje:

Cache-Control: no-cache, no-store
Pragma: no-cache
HttpWatchSupport
źródło
5
+1 To działa dla mnie w Chrome, wielkie dzięki. Używam również Response.Cache.SetAllowResponseInBrowserHistory (true); aby uniknąć historii przechowywania wpisu dla każdego żądania tej samej strony.
daniloquio
12
Najwyraźniej ktoś odkrył, że używanie SetCacheability z NoCache wyłącza również wyjściową pamięć podręczną ASP.NET (pamięć podręczną po stronie serwera). Sugerują zamiast tego użycie opcji ServerAndNoCache. codeclimber.net.nz/archive/2007/04/01/ ...
md1337
1
Aby wyjaśnić komentarze we fragmencie kodu, główną metodą jest SetCacheability. SetNoStoreto obejście IE6. Zobacz Dlaczego w odpowiedzi HTTP należy używać zarówno opcji no-cache, jak i no-store? .
Edward Brey,
3
FWIW ... Potrzebne do dodania SetNoStore dla IE10
felickz
Dla tych, którzy czytają tę stronę, którzy będą generować dynamiczne pliki PDF przez https i ustawiając nagłówki pamięci podręcznej w ten sposób, zwróć uwagę na następujący błąd IE8 i niższych: stackoverflow.com/questions/1038707/ ...
Paddy
41

Po prostu musiałem sobie z tym poradzić w mojej aplikacji ASP.NET MVC 3. Oto blok kodu, którego użyłem w pliku Global.asax do obsługi tego dla wszystkich żądań.

    protected void Application_BeginRequest()
    {
        //NOTE: Stopping IE from being a caching whore
        HttpContext.Current.Response.Cache.SetAllowResponseInBrowserHistory(false);
        HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        HttpContext.Current.Response.Cache.SetNoStore();
        Response.Cache.SetExpires(DateTime.Now);
        Response.Cache.SetValidUntilExpires(true);
    }
Adam Carr
źródło
HttpContext.Current.Response.Cache.SetAllowResponseInBrowserHistory(false)Robiło różnicę, aby zapobiec buforowania w bith IE i Firefox
Michael Kniskern
2
-1, ustawienie w tych Application_BeginRequest () powoduje wysłanie nagłówków no-cache dla elementów, które prawdopodobnie będą buforowane (pliki JavaScript, obrazy itp.). Jeszcze tego nie próbowałem, ale lokalizacja OP (ustawienie nagłówków na samej stronie ASP) jest prawdopodobnie lepsza.
Evan Haas,
Zrobiłem spodziewać tę odpowiedź do pracy, jak to jest neatest sposób, aby ustawić go w glabal.asax ale jeszcze nie radość
lawphotog
5
@Evan, Application_BeginRequest będą wywoływane tylko w przypadku żądań wysyłanych z usług IIS do ASP.NET. Często pliki statyczne, takie jak CSS, JS, obrazy, czcionki itp., Są rozszerzeniami, które są uważane za pliki statyczne z usług IIS i nie są wysyłane do środowiska uruchomieniowego ASP.NET. Jeśli usługi IIS są skonfigurowane do wysyłania wszystkich żądań do środowiska uruchomieniowego ASP.NET, to tak, dotyczy to wszystkich żądań, nawet jeśli pliki są statyczne i powinny być buforowane.
Adam Carr,
@Adam, ma sens. Cofnąłbym moje -1, ale SO mówi, że mój głos jest zablokowany :-(
Evan Haas
2

Wypróbowałem różne kombinacje i zawiodły w FireFox. Minęło trochę czasu, więc powyższa odpowiedź może działać dobrze lub mogłem coś przeoczyć.

Zawsze działało dla mnie dodanie następującego tekstu do nagłówka każdej strony lub szablonu (Strona główna w .net).

<script language="javascript" type="text/javascript">
    window.onbeforeunload = function () {   
        // This function does nothing.  It won't spawn a confirmation dialog   
        // But it will ensure that the page is not cached by the browser.
    }  
</script>

To bez wątpienia wyłączyło buforowanie we wszystkich przeglądarkach.

Steve
źródło
7
Nie jestem pewien, co to ma zrobić, ale wygląda na to, że wygląda to na wielki gruby hack, który z pewnością zawiedzie w następnej aktualizacji którejkolwiek z tych przeglądarek.
md1337
Jest to wyjaśnione na przykład na web.archive.org/web/20160112095216/http://www.hunlock.com/blogs/ ... - podsumowując, zdarzenie onbeforeunload zostało zaimplementowane do wykorzystania przez banki i zapobiega buforowaniu strony.
ChrisW
1

Znam dwa podejścia. Pierwszym jest poinformowanie przeglądarki, aby nie buforowała strony. Ustawienie odpowiedzi na brak pamięci podręcznej załatwia to, jednak jak podejrzewasz, przeglądarka często ignoruje tę dyrektywę. Innym podejściem jest ustawienie daty i godziny Twojej odpowiedzi na moment w przyszłości. Wierzę, że wszystkie przeglądarki poprawią to do aktualnego czasu, kiedy dodadzą stronę do pamięci podręcznej, ale pokaże stronę jako nowszą po dokonaniu porównania. Uważam, że mogą istnieć przypadki, w których nie dokonuje się porównania. Nie jestem pewien szczegółów i zmieniają się z każdą nową wersją przeglądarki. Uwaga końcowa Miałem więcej szczęścia ze stronami, które same się „odświeżają” (kolejna dyrektywa odpowiedzi). Wydaje się, że odświeżanie z pamięci podręcznej jest mniej prawdopodobne.

Mam nadzieję, że to pomoże.

Pat O
źródło
0

Mam zamiar przetestować dodanie tagu no-store do naszej witryny, aby sprawdzić, czy ma to wpływ na buforowanie przeglądarki (Chrome czasami buforował strony). Uważam również, że ten artykuł jest bardzo przydatny w dokumentacji dotyczącej tego, jak i dlaczego działa buforowanie i przyjrzę się następnym ETag, jeśli brak sklepu nie jest wiarygodny:

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

http://en.wikipedia.org/wiki/HTTP_ETag

Koder
źródło