Termine de procesar las directivas de reescritura en la ubicación y devuelva 301

Termine de procesar las directivas de reescritura en la ubicación y devuelva 301

Tengo lo siguiente en mi nginx.conf:

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

Para reescribir solicitudes 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"

Sin embargo, solo puedo obtener una redirección 301 si la última directiva de reescritura (que contiene la permanentbandera) coincide y se procesa, por ejemplo, mi segundo ejemplo. En los otros 2 casos obtengo una redirección temporal 302. ¿Cómo puedo procesar estas múltiples directivas de reescritura en este bloque de ubicación y devolver la redirección 301 independientemente de cuáles coincidan? Si pongo un indicador permanente en todas las directivas de reescritura, dejará de procesarse después de la primera coincidencia.

Respuesta1

Puede convertir _a .de -forma recursiva e independiente del archivo rewrite...permanent.

Por ejemplo:

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

El segundo rewritese ejecuta sólo después de que el primero rewriteno encuentra más guiones bajos. Vereste documentopara más.

Respuesta2

Puede tratar 302el código de estado como una "excepción" y "captarlo" conhttp://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;
}

La técnica es similar a la mía.301-302-redirect-w-no-http-body-text.nginx.conf, segúnuna pregunta relacionada sobre cómo producir redireccionamientos 301/302 sin cuerpo de respuesta HTTP.

Tenga en cuenta que dentro de @302to301, puede elegir entre las dos declaraciones de devolución anteriores; sin embargo, el returncódigo es irrelevante en el contexto de este controlador, ya que la error_pagedirectiva anterior garantiza que todos 302los códigos se cambien 301independientemente de cuál sea el código posterior.

En otras palabras, la única diferencia entre las dos returndeclaraciones anteriores será el contenido del cuerpo de respuesta HTTP, que de todos modos ningún navegador muestra para las respuestas 301, por lo que también podría optar por la return 300versión más corta sin cuerpo.

información relacionada