Как заставить клиентов обновить файлы JavaScript?
Проблема с кэшированием JavaScript файлов при обновлении
В настоящее время мы находимся на стадии закрытого бета-тестирования и в процессе довольно быстрых изменений. Однако, поскольку использование нашей системы начинает расти, мы планируем замедлить этот процесс. В связи с этим у нас возникает проблема: после выпуска обновлений с новыми файлами JavaScript браузеры клиентов продолжают использовать кэшированные версии файлов, и они не видят обновлений. Конечно, во время поддержки мы можем просто сообщить пользователям, чтобы они сделали обновление с помощью ctrlF5, чтобы получить актуальные файлы с сервера, но было бы предпочтительнее решить эту проблему заранее.
На данный момент мы рассматриваем вариант добавления номера версии к именам JavaScript файлов. Когда вносятся изменения, мы будем увеличивать номер версии в скрипте и обновлять все ссылки на него. Это действительно решает проблему, но обновление ссылок с каждой новой версией может стать утомительным.
Я уверен, что мы не первые, кто сталкивается с этой проблемой, поэтому решил обратиться к сообществу. Как вы обеспечиваете обновление кэша у клиентов при обновлении вашего кода? Если вы используете описанный выше метод, применяете ли вы какие-то процессы, которые упрощают эту задачу?
5 ответ(ов)
Добавление текущего времени к URL действительно является распространённым решением. Однако вы также можете управлять кэшированием на уровне веб-сервера, если это необходимо. Сервер можно настроить так, чтобы он отправлял разные HTTP-заголовки для JavaScript файлов.
Например, если вы хотите принудительно кэшировать файл не дольше, чем на 1 день, вы можете использовать:
Cache-Control: max-age=86400, must-revalidate
Если же ваша цель — обеспечить пользователей всегда последней версией файла, вы можете использовать:
Cache-Control: no-cache, must-revalidate
Таким образом, вы сможете контролировать кэширование более гибко и эффективно.
На вопрос о Google PageSpeed: «Не включайте строку запроса в URL для статических ресурсов», можно ответить так:
Проблема заключается в том, что многие прокси-серверы, включая Squid до версии 3.0, не кэшируют ресурсы, содержащие «?» в URL, даже если в ответе присутствует заголовок Cache-Control: public. Чтобы включить кэширование прокси для этих ресурсов, лучше всего удалить строки запроса из ссылок на статические ресурсы и закодировать параметры непосредственно в имена файлов.
Например, вы можете включить версию в URL: http://abc.com/**v1.2**/script.js, и использовать Apache mod_rewrite для переадресации на http://abc.com/script.js. Когда вы измените версию, браузер клиента автоматически обновит файл. Это позволит эффективно кэшировать статические ресурсы и улучшит производительность вашего сайта.
Чтобы добавить размер файла в качестве параметра загрузки, можно использовать следующий подход в вашем HTML коде:
<script type='text/javascript' src='path/to/file/mylibrary.js?filever=<?=filesize('path/to/file/mylibrary.js')?>'></script>
Это позволяет автоматически изменять параметр "filever" при каждом обновлении файла, так как он будет отражать текущий размер файла. Однако возникает вопрос: что делать, если вы обновите файл, и размер останется тем же? Вероятность такого сценария может быть не очень высокой, но она вполне реальна, особенно если вы внесли небольшие изменения в код (например, исправили опечатки или улучшили комментарии).
В результате, если файл остается того же размера, параметр "filever" не изменится, и браузер может использовать кэшированную версию. Это может привести к тому, что пользователи не увидят ваши обновления. Один из способов решения этой проблемы — добавление версии файла, например, используя конструкцию с хэшированием содержимого файла или добавление временной метки (timestamp), чтобы гарантировать, что запрос всегда будет уникальным при каждой загрузке скрипта.
Тем не менее, если вы предпочитаете использовать размер файла как способ обновления, учитывайте возможность изменения версии вручную или добавления другого параметра, который будет меняться с каждой сборкой, как временная метка или номер версии.
Не все браузеры кэшируют файлы с символом '?' в имени. Чтобы гарантировать максимальное кэширование, я решил включить версию в имя файла.
Вместо stuff.js?123
я использовал stuff_123.js
.
Я применил mod_rewrite
(или mod_redirect
, не уверен) в Apache для того, чтобы перенаправлять запросы на stuff_*.js
к stuff.js
.
Для страниц ASP.NET я использую следующий подход:
ДО
<script src="/Scripts/pages/common.js" type="text/javascript"></script>
ПОСЛЕ (принудительная перезагрузка)
<script src="/Scripts/pages/common.js?ver=<%= DateTime.Now.Ticks.ToString() %>" type="text/javascript"></script>
Добавление DateTime.Now.Ticks
отлично работает.
Таким образом, каждый раз при загрузке страницы будет использоваться новая версия скрипта, что предотвращает проблемы с кешированием.
Кэширует ли Safari на iOS 6 результаты $.ajax?
В чем разница между String.slice и String.substring?
Проверка соответствия строки регулярному выражению в JS
Существует ли ссылка на "последнюю" библиотеку jQuery в Google APIs?
Как создать диалог с кнопками "Ок" и "Отмена"