Неопределенное кэширование HTTP-ответа через Nginx завершается ошибкой

Я пытаюсь заставить nginx кэшировать некоторые из моих активов (js, css) навсегда или, по крайней мере, очень долго.

Идея состоит в том, что, как только пакет активов скомпилирован и опубликован с /assets/ Префикс URI (например, /assets/foo-{fingerprint}.js) он остается там и не нуждается в изменении.

Интернет сказал мне, что я должен написать следующее правило:

location ~ ^/assets/.*-([^.]+)\.(js|css)$ {
  gzip_static on; # there's also a .gz of the asset
  expires max;
  add_header Cache-Control public;
  add_header Last-Modified "";
  add_header ETag "";
  break;
}

Я ожидаю, что это приведет к ответам с кодом HTTP 304 "Не изменен", но я получаю согласованный HTTP 200 (ОК) каждый раз.

Я пробовал некоторые другие подходы, например:

а) явная установка времени модификации на постоянный момент времени в прошлом;

add_header Last-Modified "Thu, 01 Jan 1970 00:00:00 GMT";

б) переход на If-None-Match чеки;

add_header ETag $1;
if_modified_since off;

Тем не менее, единственное, что действительно работало по мере необходимости, это:

add_header Last-Modified "Thu, 01 Jan 2030 00:00:00 GMT";
if_modified_since before;

Я потерялся. Это противоречит всему, что я считал правильным. Пожалуйста помоги.

3 ответа

Решение

Вам следует сменить свой интернет, так как они дают вам неправильные советы.

Просто удали все add_header линии от вашего местоположения (а также излишки brake):

location ~ ^/assets/.*-([^.]+)\.(js|css)$ {
   gzip_static on; # there's also a .gz of the asset
   expires max;
}

и прочитайте документы из настоящего Интернета: http://nginx.org/r/expires и http://tools.ietf.org/html/rfc2616

...можете ли вы использовать сценарий cron для каждого экземпляра, чтобы получить желаемое время и/или отпечаток пальца для вашего конкретного файла(ов)?

Не идеально, но, вероятно, он работает для обеих стратегий кэширования с потенциальными минимальными промежутками во времени, поскольку может не соответствовать критериям кэширования.

Кажется, это часть моей конфигурации. Во время моих исследований я понял, что браузер использует эвристический анализ для проверки запросов с заголовками ConditionalGet (E-Tag, Last-Modified). Это имеет большой смысл для внутренних ответов, так что вы можете справиться с этим для экономии ресурсов сервера.

Но что касается статических файлов (js, css, images), вы можете указать браузеру, чтобы они обслуживались сразу же без какой-либо проверки условного получения. Это полезно, если вы обновите имя файла, если произойдет какое-либо изменение.

Эта часть конфигурации делает это возможным:

add_header Cache-Control public;
add_header Last-Modified "";
add_header ETag "";
Другие вопросы по тегам