場所の書き換えディレクティブの処理を終了し、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"

ただし、最後の書き換えディレクティブ (フラグを含むpermanent) が一致して処理される場合にのみ、301 リダイレクトが発生します (例: 2 番目の例)。他の 2 つのインスタンスでは、302 一時リダイレクトが発生します。このロケーション ブロックでこれらの複数の書き換えディレクティブを処理し、どれが一致しても 301 リダイレクトを返すにはどうすればよいですか? すべての書き換えディレクティブに永続的なフラグを設定すると、最初の一致後に処理が停止します。

答え1

から独立して、再帰的_に に変換できます。-rewrite...permanent

例えば:

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

2番目の方法は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、に従ってHTTPレスポンスボディなしで301/302リダイレクトを生成することに関する関連質問

内では@302to301、上記の 2 つの return ステートメントのいずれかを選択できますが、上記のディレクティブにより、後続のコードに関係なくすべてのコードが に変更されるreturnため、このハンドラーのコンテキストではコードは無関係です。error_page302301

言い換えれば、return上記の 2 つのステートメントの唯一の違いは、HTTP レスポンス ボディの内容です。これは、301 レスポンスではどのブラウザーにも表示されないため、ボディのない短いバージョンを使用する方がよいでしょうreturn 300

関連情報