Назад | Перейти на главную страницу

Завершить обработку директив перезаписи в местоположении и вернуть 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 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 версия.