Назад | Перейти на главную страницу

Добавить заголовок expires условно на основе типа mime в nginx

Запуск nginx 1.4.1 в ubuntu 12.10

Необходимо отправить заголовок с истечением срока действия условно и на основе типа mime / типа содержимого HTTP-ответа.

Добавлен этот простой фрагмент кода в location / {

if ($sent_http_content_type = "text/css") { 
expires 7d;
}

Заголовок expires не отправляется, даже если $ sent_http_content_type содержит "text / css"

Как это исправить?

Проверки расширений файлов недостаточно, потому что в моем приложении js, css изображения генерируются динамически из php. Поэтому нужно проверить пантомиму и добавить заголовки на ее основе.

Начиная с nginx 1.7.9:

map $sent_http_content_type $expires {
  default         off;
  application/pdf 42d;
  ~image/         max;
}

expires $expires;

ПРИМЕЧАНИЕ: $ sent_http_content_type действителен, но к нему нельзя получить доступ, пока сервер не обработает запрос ...

Ответ указан на карте для application/pdf который допускает значение даты или даже может быть application/pdf modified +42d например

В if директива в Nginx обрабатывается на ранней стадии на этапе перезаписи, и, следовательно, $sent_http_content_type переменная еще не инициализирована - см. этот отчет об ошибке nginx для подробностей.

РЕДАКТИРОВАТЬ: Сравнивая имена пользователей, этим отчетом об ошибке вполне может быть вы! (^_^)

Точно так же expires директива, похоже, не поддерживает переменные так же, как, например, add_header делает. Итак, поскольку вы не можете статически указывать местоположение на основе расширений файлов, я могу думать только о двух основных подходах.

Можно было бы использовать map и add_header подход, предложенный Вадимом выше, чтобы вручную устанавливать заголовки HTTP вместо разрешения expires директива сделать это. Это менее гибкий вариант, так как он не устанавливает Expires заголовок, но я надеюсь, что в наши дни любой браузер поступит правильно, просто Cache-Control устанавливается. Вот пример, который я вкратце проверил:

map $sent_http_content_type $cacheable_types {
    "text/css"    "max-age=864000";
    "image/jpeg"  "max-age=864000";
    default       "";
}

# ...

server {
    # ...
    location / {
        # ...
        add_header "Cache-Control" $cacheable_types;
    }
}

Значение 864000 составляет 10 дней в секундах - вам придется изменить это значение, как хотите. Преимущество этого подхода в том, что вы можете указать разное время для каждого типа файла и даже переопределить другие аспекты Cache-Control заголовок - вы обсуждали этот заголовок Вот, и официальная часть из HTTP RFC Вот если вы предпочитаете что-то более формальное.

Второй подход заключается в том, чтобы просто организовать, чтобы все запросы, которые приводят к кешируемому контенту, проходили по определенному пути, который вы можете использовать в location директива вроде этой:

location / {
    # ...
    location /static {
        expires 10d;
    }
}

Это упрощает настройку nginx, потому что вы можете использовать его встроенную expires директиве, но то, насколько это возможно, во многом зависит от того, можете ли вы применить этот шаблон URL-адресов в своем коде.

$ sent_http_content_type недействителен. Значения заголовка запроса доступны через $ http_название. Кроме того, для заголовка Content-type в nginx встроена переменная $ content_type.

Если вы хотите проверить $ content_type на несколько типов, лучше использовать карту:

   map $content_type $test_header {
        "text/css"  OK;
        "text/html" OK;
        ...
        default "";
   }

   server {
        location / {
             add_header "X-Test" $test_header;
        }
   }

Если $ test_header оценивается как пустая строка, заголовок не будет установлен.

Для получения дополнительной информации см .: http://nginx.org/en/docs/http/ngx_http_core_module.html#variables http://nginx.org/en/docs/http/ngx_http_map_module.html http://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header

Если вам необходимо использовать mime-тип, попробуйте:

if ($content_type ~= "text/css") { 
expires 7d;
}

Однако вы можете рассмотреть что-то вроде этого:

location ~ \.(css|js|htc)$ {
    add_header Pragma "public";
    add_header Cache-Control "max-age=31536000, public, must-revalidate, proxy-revalidate";
         log_not_found off;
         access_log off;

}
location ~ \.(html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml)$ {
    add_header Pragma "public";
    add_header Cache-Control "max-age=3600, public, must-revalidate, proxy-revalidate";
         log_not_found off;
        access_log off;

}
location ~ \.(asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mp
e|mpp|otf|odb|odc|odf|odg|odp|ods|odt|ogg|pdf|png|pot|pps|ppt|pptx|ra|ram|svg|svgz|swf|tar|tif|tiff|ttf|ttc|wav|wma|wri|xla|xls|xlsx|xlt|xlw|zip)$
 {
    add_header Pragma "public";
    add_header Cache-Control "max-age=31536000, public, must-revalidate, proxy-revalidate";
         log_not_found off;
         access_log off;

}

Мы используем это на очень загруженном сайте с очень хорошим эффектом.