Сбой кэша через параметры

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

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

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

Ответ 1

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

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

Ответ 2

Два вопроса: будет ли это эффективно разрушать кеш?

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

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

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

Ответ 3

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

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

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

Ответ 4

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

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

Ответ 5

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

  • обновлен параметр v.
  • клиент очищает свой кеш

Ответ 6

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

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

Ответ 7

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

Ответ 8

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

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

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

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

Ответ 9

Другой аналогичный подход заключается в использовании 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>

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

.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, чтобы обновить ее.

Ответ 10

<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> 

Ответ 11

 <script>
    var storedSrcElements = [
         "js/exampleFile.js",
         "js/sampleFile.js",
         "css/style.css"
          ];

    var head= document.getElementsByTagName('head')[0];
    var script;
    var link;
    var versionNumberNew = 4.6;

    for(i=0;i<storedSrcElements.length;i++){
     script= document.createElement('script');
     script.type= 'text/javascript';
     script.src= storedSrcElements[i] + "?" + versionNumberNew;
     head.appendChild(script);
    }     


     </script> 


       ### Change the version number  (versionNumberNew) when you want the new files to be loaded  ###

Ответ 12

Надеюсь, это поможет вам внедрить внешний файл JS

<script type="text/javascript"> var cachebuster = Math.round(new Date().getTime() / 1000); document.write('<scr'+'ipt type="text/javascript" src="external.js?cb=' +cachebuster+'"></scr' + 'ipt>');

Исходный код - код Cachebuster в JavaScript

Ответ 13

Кэш-пакет использует случайное число в конце URL-адреса, как показано ниже

<script type="text/javascript" language="JavaScript">
ord=Math.random()*10000000000000000;
</script>

и браузер создает что-то вроде этого,

http://ad.doubleclick.net/ABC/publisher/zone;topic=abc;sbtpc=def;cat=ghi;kw=xyz;tile=1;slot=728x90.1;sz=728x90;ord=7268140825331981?

Подробнее здесь.