it-roy-ru.com

Кеширование по парамам

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

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

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

108
Brad Herman

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

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

104
Marshall

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

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

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

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

35
Pekka 웃

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

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

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

21
jfriend00

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

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

11
hashchange

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

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

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

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

6
Ken Liu

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

5
Bobby Jack

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

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

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

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

5
user

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

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

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

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

4
alexanderbird
<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> 
2
Conete Cristian
 <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  ###
0
Teja