Завершить обработку переписать директивы в местоположении и вернуть 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 флаг) совпадения и процессы, например, мой второй пример. В двух других случаях я получаю 302 временного перенаправления. Как я могу обработать эти несколько директив перезаписи в этом блоке местоположения и вернуть перенаправление 301 независимо от того, какие из них соответствуют? Если я установлю постоянный флаг на все директивы перезаписи, он прекратит обработку после первого совпадения.

2 ответа

Решение

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

Например:

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

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

Вы можете лечить 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-redirect-w-no-http-body-text.nginx.conf, как и в случае с соответствующим вопросом о создании перенаправлений 301/302 без тела ответа HTTP.

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

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

Другие вопросы по тегам