Add expira o cabeçalho condicionalmente com base no tipo mime no nginx

4

Executando o nginx 1.4.1 no Ubuntu 12.10

A necessidade de enviar expira o cabeçalho condicionalmente e com base no tipo de mime / tipo de conteúdo da resposta HTTP.

Adicionou este simples código dentro da localização / {

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

O cabeçalho de expiração não é enviado, mesmo que $ sent_http_content_type contenha "text / css"

Como consertar isso?

Verificar as extensões de arquivo não é suficiente, porque no meu aplicativo js, css, as imagens estão sendo geradas dinamicamente a partir do php. Então, precisa verificar o mime e adicionar cabeçalhos com base nisso também.

    
por Silver Moon 13.06.2013 / 12:01

4 respostas

8

A partir do nginx 1.7.9:

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

expires $expires;

NOTA: $ sent_http_content_type é válido, mas não pode ser acessado até que o servidor tenha processado o pedido ...

A resposta está apontada para a entrada do mapa para application/pdf , que permite um valor de data, ou pode até ser application/pdf modified +42d , por exemplo

    
por 03.11.2015 / 14:06
7

A diretiva if no Nginx é processada no início do estágio de reescrita e, portanto, a variável $sent_http_content_type ainda não foi inicializada - consulte este relatório de bug nginx para detalhes.

EDIT : Comparando nomes de usuário, esse relatório de bug pode ser você, na verdade! (^ _ ^)

Da mesma forma, a diretiva expires parece não suportar variáveis da mesma forma que, por exemplo, add_header . Então, como você não está em posição de especificar estaticamente o local com base nas extensões de arquivo, só consigo pensar em duas abordagens básicas.

Um seria usar a abordagem map e add_header sugerida por Vadim acima para definir manualmente cabeçalhos HTTP em vez de permitir que a diretiva expires faça isso. Isso é um pouco menos flexível, pois não definirá o Expires do cabeçalho, mas espero que qualquer navegador nos dias atuais faça a coisa certa com apenas Cache-Control sendo definido. Aqui está um exemplo que testei brevemente:

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;
    }
}

O valor 864000 é de 10 dias em segundos - você terá que alterar isso para o que desejar. A vantagem dessa abordagem é que você pode especificar diferentes tempos para cada tipo de arquivo e até mesmo sobrepor outros aspectos do cabeçalho Cache-Control - sua discussão sobre esse cabeçalho aqui , e a parte oficial do HTTP RFC aqui se você preferir algo mais formal.

A segunda abordagem seria apenas organizar que as solicitações que resultarão em conteúdo armazenável em cache entrem em um caminho específico que você possa usar em uma diretiva location da seguinte forma:

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

Isso facilita a configuração do nginx porque você pode usar sua diretiva expires integrada, mas se é uma opção depende muito se você pode impor esse padrão de URLs em seu código.

    
por 24.06.2013 / 13:31
2

Se você precisar usar o tipo MIME, tente:

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

No entanto, você pode querer considerar algo assim:

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;

}

Nós usamos isso em um site muito ocupado, com muito bom efeito.

    
por 13.06.2013 / 18:00
1

$ sent_http_content_type é inválido. Os valores do cabeçalho da solicitação podem ser acessados via $ http_ name . Além disso, para o cabeçalho Content-type, o nginx tem a variável incorporada $ content_type.

Se você gostaria de verificar $ content_type contra um monte de tipos, seria melhor usar o mapa:

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

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

Se $ test_header for avaliado como string vazia, o cabeçalho não será definido.

Para mais informações, consulte: link link link

    
por 13.06.2013 / 14:05

Tags