Кеширование по парамам - PullRequest
110 голосов
/ 14 марта 2012

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

<link rel="stylesheet" href="base_url.com/file.css?v=1.123"/>

Два вопроса: это эффективно сломает кеш? Будет ли параметр заставлять браузер никогда не кэшировать ответ от этого URL, поскольку параметр указывает, что это динамический контент?

Ответы [ 12 ]

105 голосов
/ 14 марта 2012

Параметр ?v=1.123 указывает строку запроса, и поэтому браузер будет думать, что это новый путь, скажем, от ?v=1.0. Таким образом, он загружается из файла, а не из кэша. Как ты хочешь.

И браузер предположит, что источник останется прежним при следующем вызове ?v=1.123, а должен кэшировать его с этой строкой. Таким образом, он останется в кэше, однако ваш сервер настроен, пока вы не перейдете на ?v=1.124 или около того.

36 голосов
/ 14 марта 2012

Два вопроса: это эффективно сломает кеш?

Да. Даже Stack Overflow использует этот метод, , хотя я помню, что у них (с миллионами посетителей в день и миллионами различных версий и конфигураций клиентов и прокси-серверов) были некоторые странные крайние случаи, когда даже этого было недостаточно для сломать кеш. Но общее предположение заключается в том, что это сработает и является подходящим методом для нарушения кэширования на клиентах.

Будет ли параметр заставлять браузер никогда не кэшировать ответ от этого URL, поскольку параметр указывает, что это динамическое содержимое?

Нет. Параметр не изменит политику кэширования; заголовки кэширования, отправленные сервером, по-прежнему применяются, и если он не отправляет их, по умолчанию используется браузер.

22 голосов
/ 14 марта 2012

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

Примечание,в одном из самых крупных версионных развертываний в Интернете jQuery использует номера версий в фактическом имени файла и безопасно позволяет сосуществовать нескольким версиям без какой-либо специальной логики на стороне сервера (каждая версия - это просто отдельный файл).

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

11 голосов
/ 11 июня 2014

Как уже говорили другие, разрушение кэша с параметром запроса обычно считается плохой идеей (tm) и было в течение долгого времени.Лучше отразить версию в имени файла.Html5 Boilerplate рекомендует против использование строки запроса, среди прочего.

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

9 голосов
/ 14 марта 2012

Он разрушит кэш один раз, после того как клиент загрузит ресурс, все остальные ответы будут обслуживаться из кэша клиента, если:

  1. параметр v не обновлен.
  2. клиент очищает свой кеш
6 голосов
/ 23 декабря 2013

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

Например, если вы обслуживаетестатический контент через Akamai CDN, его можно настроить так, чтобы он игнорировал параметры запроса, чтобы предотвратить сброс кэша с помощью этого метода.

5 голосов
/ 09 февраля 2015

Найдено сравнение двух методов (строка запроса и имя файла) здесь :

Версия как строка запроса имеет две проблемы.

Во-первых, это не всегда может быть браузер, в котором реализовано кэширование, через которое нам нужно разобраться. Говорят, что некоторые (возможно, старые) прокси игнорируют строку запроса в отношении своего поведения кэширования.

Во-вторых, в некоторых более сложных сценариях развертывания, когда у вас есть несколько внешних и / или нескольких внутренних серверов, обновление происходит совсем не мгновенно. Вы должны быть в состоянии одновременно обслуживать как старую, так и новую версию ваших активов. Посмотрите, например, как это влияет на вас при использовании Google App Engine.

5 голосов
/ 13 января 2014

Это очень сильно зависит от того, насколько надежным будет ваше кэширование. Например, прокси-сервер squid (и, возможно, другие) по умолчанию по умолчанию не кэширует URL-адреса, обслуживаемые строкой запроса - по крайней мере, так было при написании этой статьи. Если вы не возражаете против определенных случаев использования, вызывающих ненужные пропуски в кеше, продолжайте с параметрами запроса. Но очень легко настроить схему очистки кэша на основе имени файла, которая позволяет избежать этой проблемы.

4 голосов
/ 05 января 2016

Другой аналогичный подход заключается в использовании htaccess mod_rewrite для игнорирования части пути при обслуживании файлов.Ваша никогда не кэшированная страница указателя ссылается на последний путь к файлам.

С точки зрения разработки это так же просто, как использовать параметры для номера версии, но это так же надежно, как и подход с использованием имени файла.

Использовать игнорируемую часть пути для номера версии иСервер просто игнорирует его и обслуживает некэшированный файл.

1.2.3/css/styles.css обслуживает тот же файл, что и css/styles.css, поскольку первый каталог удаляется и игнорируется файлом htaccess

Включая версионные файлы

<?php
  $version = "1.2.3";
?>

<html>
  <head>
    <meta http-equiv="cache-control" content="max-age=0" />
    <meta http-equiv="cache-control" content="no-cache" />
    <meta http-equiv="expires" content="0" />
    <meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
    <meta http-equiv="pragma" content="no-cache" />
    <link rel="stylesheet" type="text/css" href="<?php echo $version ?>/css/styles.css">
  </head>
  <body>
    <script src="<?php echo $version ?>/js/main.js"></script>
  </body>
</html>

Обратите внимание, что этоПодход означает, что вам нужно отключить кэширование вашей страницы индекса - Использование тегов для отключения кэширования во всех браузерах?

.htaccess файл

RewriteEngine On

# if you're requesting a file that exists, do nothing
RewriteCond %{REQUEST_FILENAME} !-f 
# likewise if a directory that exists, do nothing
RewriteCond %{REQUEST_FILENAME} !-d 

# otherwise, rewrite foo/bar/baz to bar/baz - ignore the first directory
RewriteRule ^[^/]+/(.+)$ $1 [L] 

Выможет использовать тот же подход на любой серверной платформе, которая позволяет перезаписать URL

(условие перезаписи адаптировано из mod_rewrite - переписать каталог в строку запроса, кроме / #! / )

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

2 голосов
/ 02 июня 2016
<script type="text/javascript">
// front end cache bust

var cacheBust = ['js/StrUtil.js', 'js/protos.common.js', 'js/conf.js', 'bootstrap_ECP/js/init.js'];   
for (i=0; i < cacheBust.length; i++){
     var el = document.createElement('script');
     el.src = cacheBust[i]+"?v=" + Math.random();
     document.getElementsByTagName('head')[0].appendChild(el);
}
</script> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...