Как мы контролируем кэширование веб-страниц во всех браузерах?

Я бы не стал. Я бы использовал ArrayList или отсортированную коллекцию с помощью Comparator. Сортировка LinkedList - это самая неэффективная процедура, о которой я могу думать.

1411
задан Peter Mortensen 25 June 2019 в 21:57
поделиться

11 ответов

Введение

Правильный минимальный набор заголовков, который работает на всех упомянутых клиентах (и прокси):

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

Cache-Control соответствует спецификации HTTP 1.1 для клиентов и прокси (и неявно требуется некоторыми клиентами рядом с Expires). Pragma соответствует спецификации HTTP 1.0 для доисторических клиентов. Expires соответствует спецификациям HTTP 1.0 и 1.1 для клиентов и прокси. В HTTP 1.1 Cache-Control имеет приоритет над Expires, так что это, в конце концов, только для прокси HTTP 1.0.

Если вас не волнует IE6 и его нарушенное кэширование при обслуживании страниц по HTTPS только с no-store, то вы можете опустить Cache-Control: no-cache.

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

Если вас не волнует IE6 или клиенты HTTP 1.0 (HTTP 1.1 был представлен в 1997 году), то вы можете опустить Pragma.

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

Если вам также не важны прокси HTTP 1.0, то можно опустить Expires.

Cache-Control: no-store, must-revalidate

С другой стороны, если сервер автоматически включает действительный заголовок Date, то теоретически вы можете опустить Cache-Control и полагаться только на Expires.

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

Но это может не сработать, если, например, конечный пользователь манипулирует датой операционной системы, а клиентское программное обеспечение полагается на нее.

Другие параметры Cache-Control, такие как max-age, не имеют значения, если указаны вышеупомянутые параметры Cache-Control. Заголовок Last-Modified , как указано в большинстве других ответов здесь, интересен только если вы действительно хотите кэшировать запрос, поэтому его вообще не нужно указывать.

Как его задать?

Используя PHP:

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

Используя Java Servlet, или 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.

Используя 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.

Используя ASP.NET Web API:

// `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()); 

Используя 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.

Использование 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.

Использование Ruby on Rails, или 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.

Использование 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.

Использование Python/Pyramid:

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

Использование 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.

Использование Apache . htaccess файл:

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

Использование 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" />

Метатеги HTML против заголовков HTTP-ответов

Важно знать, что когда HTML-страница обслуживается через HTTP-соединение, и заголовок присутствует в обоих заголовках HTTP-ответов и в HTML тегах, то тот, который указан в заголовке HTTP-ответа, будет иметь приоритет над метатегом HTML. Метатег HTML будет использоваться только при просмотре страницы с локального диска файловой системы через file:// URL. См. также W3 HTML spec глава 5.2.2. Будьте осторожны, если вы не указываете их программно, поскольку веб-сервер может включать некоторые значения по умолчанию.

Вообще, лучше просто не указывать метатеги HTML, чтобы избежать путаницы со стартерами, и полагаться на жесткие заголовки HTTP-ответов. Более того, конкретно эти теги являются недействительными в HTML5. Допустимы только значения http-equiv, перечисленные в спецификации HTML5.

Проверка фактических заголовков HTTP-ответа

Чтобы проверить одно и другое, вы можете увидеть/отладить их в мониторе HTTP-трафика в наборе инструментов разработчика веб-браузера. Вы можете попасть туда, нажав F12 в Chrome/Firefox23+/IE9+, затем открыв панель вкладок "Сеть" или "Net", а затем щелкнув на интересующем вас HTTP-запросе, чтобы узнать все подробности о HTTP-запросе и ответе. Скриншот ниже сделан в Chrome:

Chrome developer toolset HTTP traffic monitor showing HTTP response headers on stackoverflow.com

Я хочу установить эти заголовки и для загрузки файлов

Прежде всего, этот вопрос и ответ предназначены для "веб-страниц" (HTML-страниц), а не для "загрузки файлов" (PDF, zip, Excel и т.д.). Вам лучше иметь их в кэше и использовать какой-то идентификатор версии файла где-то в пути URI или строке запроса для принудительной повторной загрузки при изменении файла. Если вы все равно применяете такие заголовки no-cache для загрузки файлов, то остерегайтесь ошибки IE7/8 при обслуживании загрузки файлов по HTTPS вместо HTTP. Подробности см. в IE не может загрузить foo.jsf. IE не смог открыть этот интернет-сайт. Запрашиваемый сайт недоступен или не может быть найден.

2456
ответ дан 22 November 2019 в 20:19
поделиться

У меня были лучшие и самые последовательные результаты через все браузеры установкой Pragma: без кэшей

4
ответ дан petr k. 25 June 2019 в 21:57
поделиться

В дополнение к заголовкам рассматривают обслуживание Вашей страницы через https. Много браузеров не будут кэшировать https по умолчанию.

3
ответ дан Harry 25 June 2019 в 21:57
поделиться

документация PHP для функции заголовка имеет довольно полный пример (внесенный третьим лицом):

    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);
6
ответ дан Community 25 June 2019 в 21:57
поделиться

Установка измененного http заголовка на некоторую дату в 1995 обычно добивается цели.

Вот пример:

Expires: Wed, 15 Nov 1995 04:58:08 GMT
Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT
Cache-Control: no-cache, must-revalidate
6
ответ дан Anders Sandvig 25 June 2019 в 21:57
поделиться

Использование заголовка прагмы в ответе является рассказом жен. RFC2616 только определяет его как заголовок запроса

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

8
ответ дан Dave Cheney 25 June 2019 в 21:57
поделиться

RFC для HTTP 1.1 говорит, что правильный метод состоит в том, чтобы добавить HTTP-заголовок для:

Управление Кэша: без кэшей

Более старые браузеры могут проигнорировать это, если они не правильно совместимы к HTTP 1.1. Для тех можно попробовать заголовок:

Прагма: без кэшей

Это, как также предполагается, работает на браузеры HTTP 1.1.

6
ответ дан Chris Dail 25 June 2019 в 21:57
поделиться

ПРАВОВАЯ ОГОВОРКА: Я настоятельно рекомендую читать ответ @BalusC. После чтения следующего учебного руководства по кэшированию: http://www.mnot.net/cache_docs/ (я рекомендую, Вы читаете его, также), я полагаю, что он корректен. Однако по историческим причинам (и потому что я протестировал его сам), я буду включать свой исходный ответ ниже:

<час>

я попробовал 'принятый' ответ за PHP, который не работал на меня. Тогда я провел немного исследования, нашел небольшой вариант, протестировал его, и это работало. Здесь это:

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');

, Который должен работать. Проблема состояла в том, что при установке той же части заголовка дважды, если эти false не отправляется как второй аргумент функции заголовка, функция заголовка просто перезапишет предыдущее header() вызов. Так, при установке эти Cache-Control, например, если Вы не хотите помещать все аргументы в один header() вызов функции, он должен сделать что-то вроде этого:

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

См. больше подробной документации здесь .

8
ответ дан Steven Oxley 25 June 2019 в 21:57
поделиться

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

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

6
ответ дан Community 25 June 2019 в 21:57
поделиться

После небольшого количества исследования мы придумали следующий список заголовков, которые, казалось, касались большинства браузеров:

В ASP.NET мы добавили их с помощью следующего отрывка:

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 

Найденный от: http://forums.asp.net/t/1013531.aspx

20
ответ дан Edward Wilde 25 June 2019 в 21:57
поделиться

Я обнаружил, что все ответы на этой странице все еще были проблемы. В частности, я заметил, что ни один из них не остановит IE8 от использования кэшированной версии страницы, когда вы обращаетесь с ней, ударяя кнопку «Назад».

После многих исследований и тестирования я обнаружил, что только два заголовки, которые мне действительно нужны:

Cache-Control: No-Store
Варьируются: *

Для объяснения варьированного заголовка, проверьте http://www.w3.org/protocols/rfc2616/rfc2616-sec13.html#sec13.6

на IE6-8, FF1.5-3.5, Chrome 2-3, Safari 4 и Opera 9-10, эти заголовки вызвали запрошенную страницу с сервера при нажатии на ссылку на страницу или поставьте URL непосредственно в адресной строке Отказ Это покрывает 99% всех браузеров, используемых в отношении января '10.

На IE6 и Opera 9-10 ударил на заднюю кнопку, по-прежнему вызывающую загрузку кэшированной версии. На всех других браузерах я проверил, они сделали свежую версию с сервера. До сих пор я не нашел набор заголовков, которые приведут к тому, чтобы эти браузеры не вернули кэшированные версии страниц, когда вы попадаете на заднюю кнопку.

Обновление: После написания этого ответа я понял, что наш веб-сервер определяет себя как сервер HTTP 1.0. Заголовы, которые я перечислял, являются правильными для ответов с сервера HTTP 1.0, чтобы не быть кэшированным браузерами. Для сервера HTTP 1.1 посмотрите на ответ на Balusc's .

25
ответ дан 22 November 2019 в 20:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: