В моем 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
flag) совпадения и процессы, например мой 2-й пример. В двух других случаях я получаю временное перенаправление 302. Как я могу обработать эти несколько директив перезаписи в этом блоке местоположения и вернуть 301 редирект независимо от того, какие из них совпадают? Если я поставлю постоянный флаг на все директивы перезаписи, обработка прекратится после первого совпадения.
Вы можете конвертировать _
к -
рекурсивно и независимо от 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-перенаправление-ш-нет-http-body-text.nginx.conf, согласно связанный вопрос о создании переадресации 301/302 без тела ответа HTTP.
Обратите внимание, что внутри @302to301
, у вас есть выбор между двумя указанными выше операторами возврата; Однако return
код не имеет значения в контексте этого обработчика, поскольку error_page
указанная выше директива гарантирует, что все 302
коды меняются на 301
независимо от того, какой будет следующий код.
Другими словами, единственная разница между двумя return
Вышеупомянутые операторы будут содержанием тела ответа HTTP, которое ни один браузер никогда не отображает для ответа 301, так что вы можете также использовать более короткий текст без тела return 300
версия.