Отключение кеширования браузера для всех браузеров из ASP.NET

87

Мне нужно дать исчерпывающую ссылку на то, какой код ASP.NET требуется для отключения браузеров от кеширования страницы. Есть много способов повлиять на HTTP-заголовки и метатеги, и у меня создается впечатление, что для правильной работы разных браузеров требуются разные настройки. Было бы здорово получить отрывок кода с комментариями, чтобы указать, какой из них работает для всех браузеров, а какой требуется для конкретного браузера, включая версии.

Там есть огромное количество информации об этой проблеме, но мне еще предстоит найти хорошую ссылку, в которой описаны преимущества каждого метода и был ли конкретный метод заменен API более высокого уровня.

Меня особенно интересует ASP.NET 3.5 SP1, но было бы неплохо получить ответы и для более ранней версии.

В этой записи блога « Два важных различия между Firefox и IE Caching» описаны некоторые различия в поведении протокола HTTP.

Следующий пример кода иллюстрирует интересующие меня вещи.

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));
    }
}
Мартин Холлингсворт
источник
5
Я бы попытался ответить, если бы не знал, насколько невыполнима твоя задача. Управление тайником клиента похоже на попытку использовать палочки для еды длиной 10 футов, чтобы переставить мебель.
Джефф Фрикаделька Ян,
Множество ответов, охватывающих только часть проблемы, по-прежнему будут очень ценными. Пожалуйста, добавьте свои 2 цента.
Мартин Холлингсворт,

Ответы:

96

Вот что мы используем в ASP.NET:

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

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

Он прекращает кеширование в Firefox и IE, но мы не пробовали другие браузеры. Эти операторы добавляют следующие заголовки ответов:

Cache-Control: no-cache, no-store
Pragma: no-cache
HttpWatchSupport
источник
5
+1 У меня это работает в Chrome, большое спасибо. Я также использую Response.Cache.SetAllowResponseInBrowserHistory (true); чтобы избежать истории, чтобы сохранить запись для каждого запроса одной и той же страницы.
daniloquio 06
12
Очевидно, кто-то обнаружил, что использование SetCacheability с NoCache также отключает кеш вывода ASP.NET (кеш на стороне сервера). Вместо этого они предлагают использовать параметр ServerAndNoCache. codeclimber.net.nz/archive/2007/04/01/…
md1337 07
1
Чтобы прояснить комментарии во фрагменте кода, основным методом является SetCacheability. SetNoStoreэто обходной путь IE6. См. Почему в ответе HTTP следует использовать и без кеширования, и без хранения? .
Эдвард Брей
3
FWIW ... Необходимо добавить SetNoStore для
IE10
Для тех, кто читает эту страницу, кто будет выводить динамические PDF-файлы через https и устанавливать подобные заголовки кеша, обратите внимание на следующую ошибку IE8 и ниже: stackoverflow.com/questions/1038707/…
Пэдди
41

Как бы то ни было, мне просто пришлось справиться с этим в моем приложении ASP.NET MVC 3. Вот блок кода, который я использовал в файле Global.asax для обработки всех запросов.

    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);
    }
Адам Карр
источник
Это HttpContext.Current.Response.Cache.SetAllowResponseInBrowserHistory(false)имело значение для предотвращения кеширования в битах IE и FireFox
Майкл Книскерн
2
-1, установка в этих Application_BeginRequest () вызывает отправку заголовков без кеширования для элементов, которые вы, вероятно, захотите кэшировать (файлы JavaScript, изображения и т. Д.). Я еще не пробовал, но расположение OP (установка заголовков на самой странице ASP), вероятно, лучше.
Эван Хаас
Я ожидал, что этот ответ сработает, так как это лучший способ установить его в glabal.asax, но пока без радости
lawphotog
5
@Evan, Application_BeginRequest будет вызываться только для запросов, отправленных из IIS в ASP.NET. Часто статические файлы, такие как CSS, JS, изображения, шрифты и т. Д., Являются расширениями, которые считаются статическими файлами из IIS и не отправляются в среду выполнения ASP.NET. Если IIS настроен для отправки всех запросов в среду выполнения ASP.NET, тогда да, это будет применяться ко всем запросам, даже если файлы статические и должны быть кэшированы.
Адам Карр
@ Адам, имеет смысл. Я бы отменил свой -1, но ТАК говорит, что мой голос заблокирован :-(
Эван Хаас
2

Я пробовал различные комбинации и терпел неудачу в FireFox. Прошло некоторое время, поэтому ответ выше может работать нормально, или я, возможно, что-то пропустил.

У меня всегда получалось добавлять следующее в заголовок каждой страницы или в шаблон (мастер-страница в .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>

Это в обязательном порядке отключило для меня кеширование во всех браузерах.

Стив
источник
7
Не уверен, что это должно делать, но похоже, что это большой жирный хакер, который обязательно потерпит неудачу в следующем обновлении любого из этих браузеров.
md1337 07
Это объясняется, например, на веб-сайте web.archive.org/web/20160112095216/http://www.hunlock.com/blogs/… - в итоге событие onbeforeunload было реализовано для использования банками и предотвращает кэширование страницы.
ChrisW
1

Я знаю два подхода. Первый - указать браузеру не кэшировать страницу. Установка ответа на отсутствие кеша позаботится об этом, однако, как вы подозреваете, браузер часто игнорирует эту директиву. Другой подход - установить дату и время вашего ответа на точку в будущем. Я считаю, что все браузеры исправят это до текущего времени, когда добавят страницу в кеш, но при сравнении будет отображаться страница как более новая. Я считаю, что в некоторых случаях сравнение не проводится. Я не уверен в деталях, и они меняются с каждой новой версией браузера. Последнее замечание. Мне больше повезло со страницами, которые «обновляются» (еще одна директива ответа). Похоже, что обновление из кеша с меньшей вероятностью.

Надеюсь, это поможет.

Пэт О
источник
0

Я собираюсь протестировать добавление тега no-store на наш сайт, чтобы увидеть, влияет ли это на кеширование браузера (Chrome иногда кэширует страницы). Я также нашел эту статью очень полезной для документации о том, как и почему работает кеширование, и я посмотрю на ETag, если метод no-store ненадежен:

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

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

Кодер
источник