Истекает заголовок на основе динамического Content-Type в nginx
У меня есть веб-сайт PHP, где некоторый контент генерируется пользователем. Например, пользователи могут загружать фотографии, размер которых изменяется и может быть запрошен. Я хотел бы указать Expires
заголовок (для кэширования) на основе типа MIME (Content-Type
заголовок ответа) в моей конфигурации nginx.
Это моя текущая конфигурация (мой хост автоматически добавляет http{}
а также server{}
):
charset utf-8;
types {
text/css css;
text/javascript js;
}
gzip on;
gzip_types text/html text/css text/javascript application/json image/svg+xml;
location / {
if (!-e $request_filename) {
rewrite . /index.php last;
break;
}
set $expire 0;
if ($upstream_http_content_type = image/jpeg) { set $expire 1; }
if ($upstream_http_content_type = image/png) { set $expire 1; }
if ($upstream_http_content_type = image/gif) { set $expire 1; }
if ($upstream_http_content_type = image/svg+xml) { set $expire 1; }
if ($upstream_http_content_type = text/css) { set $expire 1; }
if ($upstream_http_content_type = text/javascript) { set $expire 1; }
if ($expire = 1) {
expires max;
}
}
Это работает для статических файлов (например, .png
файлы - они получают право Expires
заголовок), но это не влияет на динамически генерируемый контент из index.php
(нет Expires
заголовок вообще). Кто-то знает, что я делаю не так?
1 ответ
В вашем location
Блок некуда, когда вы передаете запрос в php веб-приложение, поэтому я могу предположить, что вы делаете это где-то еще, например, в location
блок, как этот:
location /index.php {
# your code
}
С вашей конфигурацией, когда пользователь запрашивает статический файл, который существует тогда первым if
директива не рассчитана и все идет хорошо. Проблемы начинаются, когда пользователь запрашивает динамические файлы, тогда nginx вводит ваш первый if
блок:
if (!-e $request_filename) {
rewrite . /index.php last;
break;
}
И вот что случилось? Ты используешь last
флаг с rewrite
директива, а что говорит по этому поводу документ nginx?
last - завершает обработку текущих директив перезаписи и перезапускает процесс (включая переписывание) с поиском совпадения по URI из всех доступных местоположений.
Согласно этой спецификации, когда файл динамический, вы сделали переписать index.php
и исполнение уходит if
блок и даже целый location
блок и следующий if
блок для проверки content-type
даже не проверены. Я полагаю, найти location
для URL /index.php
и там вы не установите expires max
,
Вы понимаете это расширение вашей проблемы?
Разрешение на это слишком переместить / скопировать ваш последовательный if
блок для проверки content-type
поместить место, где ваша конфигурация передает выполнение php веб-приложению (index.php)... или удалить last
флаг от rewrite
директива, если это не создает никаких других проблем.
Окей, так как я обещал немного исправить ваш файл conf: измените ваш location
блок с этим двумя:
location /index.php {
if ($upstream_http_content_type ~ "(image/jpeg)|(image/png)|(image/gif)|(image/svg+xml)|(text/css)|(text/javascript)") {
expires max;
}
if ($sent_http_content_type ~ "(image/jpeg)|(image/png)|(image/gif)|(image/svg+xml)|(text/css)|(text/javascript)") {
expires max;
}
}
location / {
if ($upstream_http_content_type ~ "(image/jpeg)|(image/png)|(image/gif)|(image/svg+xml)|(text/css)|(text/javascript)") {
expires max;
}
if ($sent_http_content_type ~ "(image/jpeg)|(image/png)|(image/gif)|(image/svg+xml)|(text/css)|(text/javascript)") {
expires max;
}
try_files $uri /index.php =404;
}
Первый location
блок для вашего index.php
и динамический ответ, в то время как второй для статических файлов. Во втором мы добавляем заголовок expires max
в качестве верхнего заголовка и в качестве стандартного заголовка (просто чтобы быть уверенным). Я использую здесь один if
блок для всех типов, которые вы определили в вашей конфигурации с помощью регулярного выражения. В конце мы используем try_files
директива, которая означает, что если возможно получить статический файл на основе URL, он будет получен, и другим способом попробуйте url /index.php или просто вернитесь с http 404. Первый блок местоположения предназначен только для URL /index.php
, Я нигде не нашел в твоем конфиге root
директива, которая должна указывать на корневую папку вашего приложения. Попробуйте добавить это также ( root doc).
Я надеюсь, что это решит ваши проблемы.