Кеширование по парамам
Мы хотим кэшировать бюст на производственных развертываниях, но не тратить кучу времени на разработку системы для этого. Я думал о том, чтобы применить параметр к концу файлов css и js с номером текущей версии:
<link rel="stylesheet" href="base_url.com/file.css?v=1.123"/>
Два вопроса: будет ли это эффективно сломать кеш? Будет ли параметр заставлять браузер никогда не кэшировать ответ от этого URL, поскольку параметр указывает, что это динамическое содержимое?
11 ответов
Парам ?v=1.123
указывает строку запроса, и поэтому браузер будет думать, что это новый путь, скажем, ?v=1.0
, Таким образом, он загружается из файла, а не из кэша. Как ты хочешь.
И браузер предположит, что источник останется прежним при следующем вызове. ?v=1.123
и должен кэшировать его с этой строкой. Таким образом, он будет оставаться в кэше, однако ваш сервер настроен, пока вы не перейдете к ?v=1.124
или так далее.
Два вопроса: будет ли это эффективно сломать кеш?
Да. Даже Stack Overflow использует этот метод, хотя я помню, что у них (с миллионами посетителей в день и миллионами различных версий и конфигураций клиентов и прокси-серверов) были некоторые странные крайние случаи, когда даже этого было недостаточно, чтобы сломать кеш. Но общее предположение заключается в том, что это сработает и является подходящим методом для нарушения кэширования на клиентах.
Будет ли параметр заставлять браузер никогда не кэшировать ответ от этого URL, поскольку параметр указывает, что это динамическое содержимое?
Нет. Параметр не изменит политику кэширования; заголовки кэширования, отправленные сервером, по-прежнему применяются, и если он не отправляет их, по умолчанию используется браузер.
Безопаснее указывать номер версии в фактическом имени файла. Это позволяет нескольким версиям существовать одновременно, так что вы можете развернуть новую версию, и если все еще существуют кэшированные HTML-страницы, которые запрашивают более старую версию, они получат версию, которая работает с их HTML.
Обратите внимание, что в одном из самых крупных версионных развертываний в Интернете jQuery использует номера версий в фактическом имени файла и безопасно позволяет сосуществовать нескольким версиям без какой-либо специальной логики на стороне сервера (каждая версия - это просто отдельный файл).
Это отключает кэш один раз, когда вы развертываете новые страницы и новые связанные файлы (что вам нужно), и с тех пор эти версии могут эффективно кэшироваться (что вам тоже нужно).
Как уже говорили другие, перебор кеша с параметром запроса обычно считается плохой идеей (tm) и был в течение долгого времени. Лучше отразить версию в имени файла. Html5 Boilerplate рекомендует, среди прочего, не использовать строку запроса.
Тем не менее, из рекомендаций, которые я видел, которые ссылались на источник, все, кажется, взяли свою мудрость из статьи Стива Соудерса 2008 года. Его выводы основаны на поведении прокси в то время, и они могут или не могут быть актуальны в эти дни. Тем не менее, при отсутствии более актуальной информации, изменение имени файла является безопасной опцией.
Он один раз разрушит кеш, после того как клиент загрузит ресурс, все остальные ответы будут отправляться из кеша клиента, если только:
- Параметр v обновлен.
- клиент очищает свой кеш
В целом это должно быть хорошо, но возможно, что это не будет работать, если есть промежуточный кеш (прокси), который настроен на игнорирование параметров запроса.
Например, если вы обслуживаете статический контент через Akamai CDN, его можно настроить так, чтобы он игнорировал параметры запроса, чтобы предотвратить сброс кэша с помощью этого метода.
Нашел сравнение двух методов (строка запроса и имя файла) здесь:
Версия как строка запроса имеет две проблемы.
Во-первых, это не всегда может быть браузер, который реализует кэширование, через которое мы должны разобраться. Говорят, что некоторые (возможно, старые) прокси игнорируют строку запроса в отношении их поведения кэширования.
Во-вторых, в некоторых более сложных сценариях развертывания, когда у вас есть несколько внешних и / или нескольких внутренних серверов, обновление происходит совсем не мгновенно. Вы должны быть в состоянии одновременно обслуживать как старую, так и новую версии своих активов. Посмотрите, например, как это влияет на вас при использовании Google App Engine.
Это очень сильно зависит от того, насколько надежным будет ваше кэширование. Например, прокси-сервер squid (и, возможно, другие) по умолчанию не кэширует URL-адреса, обслуживаемые строкой запроса - по крайней мере, так было при написании этой статьи. Если вы не возражаете против определенных случаев использования, вызывающих ненужные пропуски в кеше, продолжайте с параметрами запроса. Но очень легко настроить схему очистки кэша на основе имени файла, которая позволяет избежать этой проблемы.
Другой подобный подход заключается в использовании htaccess mod_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>
Обратите внимание, что этот подход означает, что вам необходимо отключить кэширование страницы индекса. - Использовать теги для отключения кэширования во всех браузерах?
файл.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 для ее обновления.
Надеюсь, это поможет вам ввести внешний 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>');
</script>
Источник - код Cachebuster на JavaScript
<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>
<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 ###
Для кэширования пакета используйте случайное число в конце 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?
Подробнее здесь.