Conclua o processamento das diretivas de reescrita no local e retorne 301

Conclua o processamento das diretivas de reescrita no local e retorne 301

Eu tenho o seguinte no meu nginx.conf:

location ~* /collections.*?products/([^/]+)/?$ {
    rewrite ^/collections.*?products/([^/]+)/?$ /$1.html;
    rewrite ^([^_]*)_([^_]*)_(.*)$ $1-$2-$3;
    rewrite ^([^_]*)_(.*)$ $1-$2 permanent; 
}  

Para reescrever solicitações como

"/collections/products/someproduct/" to "/someproduct.html"
"/collections/products/some_product/" to "/some-product.html"
"/collections/products/some_other_product/" to "/some-other-product.html"

No entanto, só consigo fazer com que um redirecionamento 301 ocorra se a última diretiva de reescrita (contendo o permanentsinalizador) corresponder e processar, por exemplo, meu segundo exemplo. Nas outras duas instâncias, recebo um redirecionamento temporário 302. Como posso processar essas múltiplas diretivas de reescrita neste bloco de localização e retornar o redirecionamento 301, independentemente de quais correspondem? Se eu colocar um sinalizador permanente em todas as diretivas de reescrita, o processamento será interrompido após a primeira correspondência.

Responder1

Você pode converter _para -recursivamente e independentemente do arquivo rewrite...permanent.

Por exemplo:

location ~* /collections.*?products/([^/]+)/?$ {
    rewrite ^(.*)_(.*)$ $1-$2 last;
    rewrite ^/collections.*?products/([^/]+)/?$ /$1.html permanent; 
}

O segundo rewriteé executado somente depois que o primeiro rewritenão consegue encontrar mais sublinhados. Veresse documentopara mais.

Responder2

Você pode tratar 302o código de status como uma “exceção” e “capturá-lo” comhttp://nginx.org/r/error_page.

location ~* /collections.*?products/([^/]+)/?$ {
    rewrite ^/collections.*?products/([^/]+)/?$ /$1.html;
    rewrite ^([^_]*)_([^_]*)_(.*)$ $1-$2-$3;
    rewrite ^([^_]*)_(.*)$ $1-$2 permanent;
    error_page 302 =301 @302to301;
}
location @302to301 {
    return 300; # 300 is just a filler here, error_page dictates status code
    #return 301 $sent_http_location;
}

A técnica é semelhante à minha301-302-redirect-w-no-http-body-text.nginx.conf, conformeuma questão relacionada sobre a produção de redirecionamentos 301/302 sem corpo de resposta HTTP.

Observe que dentro de @302to301, você pode escolher entre duas instruções de retorno acima; entretanto, o returncódigo é irrelevante no contexto deste manipulador, pois a error_pagediretiva acima garante que todos 302os códigos sejam alterados, 301independentemente de qual seja o código subsequente.

Em outras palavras, a única diferença entre as duas returndeclarações acima será o conteúdo do corpo da resposta HTTP, que nenhum navegador mostra para respostas 301, então, você também pode optar pela return 300versão mais curta e sem corpo.

informação relacionada