Завершите обработку директив перезаписи в местоположении и верните 301

Завершите обработку директив перезаписи в местоположении и верните 301

У меня в nginx.conf есть следующее:

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

Чтобы переписать такие запросы, как

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

Однако я могу получить перенаправление 301 только в том случае, если последняя директива перезаписи (содержащая флаг permanent) совпадает и обрабатывается, например, мой 2-й пример. В других 2 случаях я получаю временное перенаправление 302. Как мне обработать эти несколько директив перезаписи в этом блоке расположения и вернуть перенаправление 301 независимо от того, какие из них совпадают? Если я поставлю постоянный флаг на все директивы перезаписи, обработка прекратится после первого совпадения.

решение1

Вы можете преобразовать _в -рекурсивно и независимо от rewrite...permanent.

Например:

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

Второй rewriteвыполняется только после того, как первый rewriteне может найти больше ни одного подчеркивания. Смотретьэтот документдля большего.

решение2

Вы можете рассматривать 302код состояния как «исключение» и «перехватывать» его с помощьюhttp://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;
}

Техника похожа на мою301-302-перенаправление-w-no-http-body-text.nginx.conf, согласносвязанный вопрос о создании перенаправлений 301/302 без тела ответа HTTP.

Обратите внимание, что внутри @302to301у вас есть выбор между двумя операторами возврата, указанными выше; однако returnкод не имеет значения в контексте этого обработчика, поскольку error_pageуказанная выше директива гарантирует, что все 302коды будут изменены 301независимо от того, какой будет последующий код.

Другими словами, единственной разницей между двумя returnприведенными выше утверждениями будет содержимое тела HTTP-ответа, которое ни один браузер в любом случае не отображает для ответов 301, поэтому вы можете использовать более короткую return 300версию без тела.

Связанный контент