Статические файлы (картинки, скрипты, css), как правило кешируются для более быстрой работы сайтов (уменьшение трафика - это уже скорее побочное явление). И в этом, казалось бы, нет ничего плохого. За исколючением одного - когда это самое кеширование мешает разработке. В моем случае используется стандартная связка nginx для статики + Tornado для всего остального. Но так как создавать вторую версию конфигурации nginx’а с отключенным кешированием мне не хотелось, да и в процессе разработке во многих случаях можно обойтить самим лишь Tornado, то я решил отключить кеширование в Tornado.
За отдачу статических файлов в Tornado отвечает StaticFileHandler. То логичным было предположить что кеширование отключается где-то в его настройках. Но единственное что там можно сделать, это переопределить метод get_cache_time, который и так во всех случаях возвращает 0. Исключение составляет лишь случай, когда в параметрах запроса есть ключ “v” - тогда время жизни кеша будет 10 лет.
Если посмотреть внимательно на код StaticFileHandler’а, в частности метогда, то увидем что 304-й ответ (not modified) выдаются только при соблюдении такого условия: в заголовках запроса (request headers) есть “If-Modified-Since” и время модификации файла больше, чем значение “If-Modified-Since”. Казалось бы все хорошо, но вот только дата последней модификации файла никак не может нам гарантировать, что содержимое не поменялось. В качестве значения заголовка “If-Modified-Since” браузеры передают то, что они получили от сервера на предыдущий запрос к данному ресурсу в заголовке “Last-Modified”. Таким образом для отключения кеширования статики необходимо отдать заведомо старое значение Last-Modified. Делается жто так:
Тут я указываю дату модификации на год меньше текущей даты. Так же для большей уверености выставляю значение “Expires” в 0, что сообщит браузеру о необходимости заново загрузить файл. И последнее - “Cache-Control=‘no-cache, must-revalidate” для большей уверенности.
Теперь останется лишь указать наш хэндлев к как обработчик запросов к статике и все готово. А учитывая что в testing и production окружениях наверняка будет использоваться nginx, то код можно не менять, т.к. до нашего обаботчика запросы не дойдут, их обработает nginx.
Исходный код описанного хэндлера: https://github.com/e0ne/BlogSamples/blob/master/tornado-nocache/handlers.py