В этой статье будет описаны стандартные заголовки, которые работают между браузером и сервером для кеширования файлов.
Перед тем, как начать.
Лучше просто ничего не трогать. Статические файлы, когда раздаются nginx’ом по дефолту настроены нормально.
Схематично
Нет кеша
sequenceDiagram participant b as browser participant s as server b-->>+s: GET / s->>-b: Cache-Control: no-cache
Кеширование статики
sequenceDiagram participant b as browser participant s as server b-->>+s: GET /main.abcdef.js s->>-b: Cache-Control: public, max-age=3600, immutable <br/>ETag: some <br/> Last-Modified: Nov 11 2024 00:00:00 GMT b-->>+s: <br/> GET /main.abcdef.js <br/> If-None-Match: some <br/> If-Modified-Since: date alt Hit Cache s->>b: 304 Not Modified else Miss Cache s->>-b: 200 OK + file + new ETag & Last-Modified end opt Revalidate from client b-->>s: Pragma: no-cache s->>b: Last version end
Настройки
Основной заголовок, в котором помещается контроль за кешированием браузера - Cache-Control
. Он имеет формат: command[=value]
. Перечислять все смысла нет, поэтому стандартные практики.
Никакого кеша:
Cache-Control: private, no-cache, must-revalidate
Для статических файлов (не забываем добавлять хеш в путь или название файла):
Cache-Control: public, max-age=31536000, immutable
В формирование ключа для кеша в браузере используется:
- домен
- путь
- GET параметры
Перепроверка/revalidation кеша
При проверке кеша браузер ориентируется на два заголовка от сервера:
- ETag - это хеш версия объекта, который мы отдавали. В nginx он формируется как
"<hex(size)>-<hex(mtime)>"
- Last-Modified - дата последнего изменения файла.
Для перепроверки кеша браузер отправляет их обратно на сервер:
- If-None-Match - передаём последний сохранённый ETag для проверки.
- If-Modified-Since - передаём последнюю сохранённого файла.
- Если представлены оба заголовка, то If-None-Match считается приоритетным.
Дальше сервер отвечает 304 Not Modified - если можно дальше использовать версию из кеша. Или 200 OK, чтобы пределать новую версию.