Задать вопрос

Обход кэширования js/css

Всем привет! Хочу задать совсем простой вопрос:

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

Пока спасаемся ручным переименованием файлов перед каждым обновлением, но продолжать это делать очень не хочется…
Возможно есть какой то более автоматизированный способ прописывать версию скрипта и в название файла и в заголовки шаблонов?
  • Вопрос задан
  • 50081 просмотр
Подписаться 16 Простой Комментировать
Решения вопроса 1
slang
@slang
Наиболее простой для Вас вариант, как мне кажется — это, конечно же, использовать GET-параметр после скрипта:
<script src="/js/script.js?1273455236"></script>

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

Конечно же такие проверки задействуют файловую подсистему, интерпретатор и т.д., что не очень быстро и в продакшн я бы такую схему не советовал, но, для реалий быстро-изменяющегося проекта — хороший выстрел в обоих зайцев.
Ответ написан
Пригласить эксперта
Ответы на вопрос 11
iswitch
@iswitch
Geek, Programmer, ????
main.js?123
main.css?123
Если файлу передаются параметры (?123), то браузер обязан его загрузить заного.
Ответ написан
@Serator
А не лучше ли выкинуть из головы все эти анахронизмы (аль даже маразмы), описанные выше, и использовать то, что собственно и было реализовано под вашу задачу, то бишь ETag. Подробнее почитаете в википедии, аль где-нибудь еще (информации достаточно много).

+ в том, что все происходит автоматически и при этом файл кешируется.

Пример использования для ".htaccess":

# Настраиваем ETag на время последнего изменения файла и его размер
FileETag MTime Size
Ответ написан
@Demetros
для nginx как-то так

location ~* /static/\d+/ {
   alias /path/to/static;
}


в шаблоне при изменении скриптов/стилей увеличиваете циферку

<script src="/static/123/js/core.js"></script>
Ответ написан
Комментировать
@v1z
если нужно отключить кеширование для какого-то файла вообще, то в шаблоне в конец файла дописывать юникстайм (время в секундах с момента эпохи юникс)

style.css?1292227150

В Ruby это Time.now.to_i, аналогичные функции есть почти во всех языках.
Ответ написан
Комментировать
Имеется константа, напримеп, REVISION которая равна номеру текущей ревизии статики.
Вся статика подключается как /css/REVISION/main.css, /js/REVISION/core.css

В nginx написано как указано выше:
Ответ написан
@servitpol
<script src="js/jquery.canvasjs.min.js?v=<?php echo filectime('js/jquery.canvasjs.min.js'); ?>"></script>
Ответ написан
Комментировать
@Demetros
Если нужно отключить кеширование совсем, то по моему мнению самый надежный способ — это генерация случайного числа как описано выше и добавление заголовка Cache-Control: no-cache, no-store в ответ сервера.
Ответ написан
Комментировать
JeanLouis
@JeanLouis
Так же можете использовать http-заголовок Last-Modified
Ответ написан
Комментировать
@kmike
Т.к. технологии реализации в вопросе нет, то напишу, как с этим в django. Для django есть с десяток библиотек, которые этим занимаются: djangopackages.com/grids/g/asset-managers/

После первоначальной настройки все работает автоматически: файл поменялся => на сервере статика пересобирается, пересжимается, к собранному файлу приписывается новый unixtime и в html обновляется путь.
Ответ написан
Комментировать
Комментировать
vool
@vool
Разработчик
В head добавь:
<head> 
   ... 
   <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" /> 
    <meta http-equiv="cache-control" content="max-age=0" /> 
    <meta http-equiv="Pragma" content="no-cache" /> 
    <meta http-equiv="Expires" content="0" /> 
</head>
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы