Что делает добавление «? V = 1» к URL-адресам CSS и Javascript в тегах ссылок и сценариев?

138

Я просматривал шаблонный шаблон HTML 5 (с http://html5boilerplate.com/ ) и заметил использование "?v=1"URL-адресов при обращении к файлам CSS и Javascript.

  1. Что делает добавление "?v=1"к ссылкам CSS и Javascript в тегах ссылок и скриптов?
  2. Не все URL-адреса Javascript имеют "?v=1"(пример из приведенного ниже примера:) js/modernizr-1.5.min.js. Есть ли причина, почему это так?

Образец из их index.html:

<!-- CSS : implied media="all" -->
<link rel="stylesheet" href="css/style.css?v=1">

<!-- For the less-enabled mobile browsers like Opera Mini -->
<link rel="stylesheet" media="handheld" href="css/handheld.css?v=1">

<!-- All JavaScript at the bottom, except for Modernizr which enables HTML5 elements & feature detects -->
<script src="js/modernizr-1.5.min.js"></script>

<!------ Some lines removed ------>

<script src="js/plugins.js?v=1"></script>
<script src="js/script.js?v=1"></script>

<!--[if lt IE 7 ]>
  <script src="js/dd_belatedpng.js?v=1"></script>
<![endif]-->


<!-- yui profiler and profileviewer - remove for production -->
<script src="js/profiling/yahoo-profiling.min.js?v=1"></script>
<script src="js/profiling/config.js?v=1"></script>
<!-- end profiling code -->
maxyfc
источник

Ответы:

175

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

/Resources/Combined.css?v=x.x.x.buildnumber

Поскольку это меняется с каждым новым нажатием кода, клиент вынужден получать новую версию только из-за строки запроса. Посмотрите на эту страницу (на момент ответа), например:

<link ... href="http://sstatic.net/stackoverflow/all.css?v=c298c7f8233d">

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

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

Ник Крейвер
источник
3
@Free - отправленный вчера заголовок элемента управления кэшем не может сказать клиенту, что файл изменился сегодня (клиент даже не проверяет), URL-адрес может. Можете ли вы объяснить, что мне там не хватает?
Ник Крейвер
8
@Free - способ кэширования этих файлов - это навсегда , что означает, что клиент никоим образом не проверяет, изменен ли файл. Это означает, что они никогда не получат обновленный файл ... если не изменить URL-адрес, как это происходит с техникой выше. Вы получаете максимальный срок службы кэша на клиенте (наименьшее количество HTTP-запросов), но клиент мгновенно обновляется, когда файл действительно изменяется . Точно, как бы вы достигли всего этого, используя только заголовки управления кешем?
Ник Крейвер
4
@Free - Stack Overflow получает 5 миллионов посетителей в месяц, ваш подход будет иметь 2 эффекта: а) гораздо больше запросов и данных, отправляемых на наши серверы и с них, и б) пользователи не получат сразу новый JavaScript / CSS (например, когда у нас была ошибка, или HTML изменялся, требуя нового JS / CSS). Естественное истечение срока действительно не вариант здесь. Метод, который вы предлагаете, был бы технически гораздо менее эффективным, и в результате на регулярной основе бывали реальные ошибки пользователей ... которые на самом деле неприемлемы ни на одном крупном сайте (и на самом деле он не должен быть ни на одном сайте).
Ник Крейвер
2
@ Free - 5 миллионов - это 5 миллионов посетителей в месяц , так как мы используем много раз в день , запросы во много раз больше. С точки зрения загрузки страниц HTML мы говорим чуть более 110 миллионов в месяц (и растем ... опять же, это только загрузка страниц HTML). Для а) да, много больше или больше перерывов, это компромисс в любом случае времени кеша по сравнению с клиентами, имеющими правильный контент. Кроме того, ваша логика для б) ошибочна, HTML не кэшируется, поэтому использование с кэшированным JS, которое больше не работает, означает , что затрагиваются только кэшированные пользователи, а не то, что они защищены.
Ник Крейвер
5
@GMsoF v просто представляет для нас «версию», это совершенно произвольный выбор. Любая строка запроса значения будет работать, например, это может быть так же легко? Jejdutogjesudo =
Ник
23

Это гарантирует, что вы получаете последнюю версию файла css или js с сервера.

И позже вы можете добавить, "?v=2"если у вас есть более новая версия "?v=3", "?v=4"и так далее.

Обратите внимание, что вы можете использовать любой querystring, 'v' не является обязательным, например:

"?blah=1"будет работать так же.

И

"?xyz=1002" буду работать.

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

Амр Элгархи
источник
13

Хеш-решение хорошо, но не очень удобно для чтения человеком, когда вы хотите знать, какая версия файла находится в вашей локальной веб-папке. Решением является date/timeпечать вашей версии, чтобы вы могли легко сравнить ее с файлом вашего сервера.

Например, если ваш .js or .cssфайл датирован 2011-02-08 15:55:30(последняя модификация), то версия должна быть равна.js?v=20110208155530

Должно быть легко читать свойства любого файла на любом языке. В ASP.Net это действительно легко ...

".js?v=" + File.GetLastWriteTime(HttpContext.Current.Request.PhysicalApplicationPath + filename).ToString("yyMMddHHHmmss");

Потому что сначала сделайте это красиво в свойствах / функциях, и все готово. Больше никаких оправданий.

Удачи, ст.

Искусство
источник
2
Что делать, если вы создаете свой сайт только с помощью HTML JS и CSS. Тогда как мы можем автоматически внедрить имя версии в статические ресурсы?
Нишант Наир
@ Whizkid747 с поздним ответом, но для новичков любая используемая вами система сборки / сборки сайта должна иметь способ получить дату в миллисекундах, которую вы можете использовать в качестве версии, в противном случае, если вы не используете систему сборки // сборки Вы должны написать это сами.
AntK
7

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

Это часто может привести к неожиданному поведению при выпуске новой версии файла JS.

Поэтому обычной практикой является добавление параметра QueryString в URL-адрес файла javascript. Таким образом, браузер кэширует файл Javascript с v = 1. Когда вы выпускаете новую версию своего файла javascript, вы меняете URL-адрес на v = 2, и браузер будет вынужден загрузить новую копию.

Робин Дэй
источник
какие именно браузеры? даже самые причудливые IE 5 и 6 подчинялись заголовкам управления кэшем.
Бесплатная консультация
7

Для того, чтобы ответить на ваши вопросы;

«? v = 1» это написано только потому, что вы загружаете свежую копию файлов css и js, а не используете из кеша браузера.

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

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

Вот статья, в которой объясняется, как и зачем делать версионирование файлов CSS и JS.

Тапан Кумар
источник
2

Во время разработки / тестирования новых выпусков кеш может быть проблемой, потому что браузер, сервер и даже иногда 3G-оператор (если вы делаете мобильное развертывание) будут кешировать статический контент (например, JS, CSS, HTML, img). Вы можете преодолеть это, добавив номер версии, случайное число или метку времени в URL, например: JSP:<script src="js/excel.js?time=<%=new java.util.Date()%>"></script>

Если вы используете чистый HTML (вместо страниц сервера JSP, ASP, PHP), сервер вам не поможет. В браузере ссылки загружаются до запуска JS, поэтому вы должны удалить ссылки и загрузить их с помощью JS.

// 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);
}
Конете Кристиан
источник
0

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

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

Phugo
источник
-2

Как уже упоминалось, это используется для очистки кэша внешнего интерфейса. Чтобы реализовать это, я лично нашел полезным пакет nru grunt-cache-bust.

ОЗУ
источник
1
Хотя эта ссылка может ответить на вопрос, ответы только на ссылки не рекомендуются при переполнении стека, вы можете улучшить этот ответ, взяв жизненно важные части ссылки и вставив его в свой ответ, это гарантирует, что ваш ответ все еще остается ответом, если ссылка будет изменена или удалено :)
WhatsThePoint