Apache mod_rewrite RewriteRule は L フラグにもかかわらずループします

Apache mod_rewrite RewriteRule は L フラグにもかかわらずループします

Apache/2.4.54。
類似のURL(例:/anystuff.htm)を外部的に「/something」にリダイレクトし、内部的には「something.html」にリダイレクトすることを目指しています。しかし、次のルールは停止する代わりにループを引き起こします。つまり、「something」が一致します。

RewriteEngine On
RewriteBase /
RewriteRule ^something$ something.html [L]
RewriteRule ^(some|thing|any|stuff).*/?$ /something [L, R=301,NC]

しかし、「/something」へのリダイレクトが 2 番目のルールによって再び一致し、ループが発生するため、「L」ディレクティブは効果がないようです。

テストhttps://htaccess.madewithlove.com/期待通りに動作するはずです。ログを有効にすることはできないと思います :-(

答え1

このLフラグは書き換えエンジンの現在のパスを停止するだけで、全て処理中。後続のディレクティブはすぐには処理されませんが、(ディレクトリ コンテキストでは)書き換えプロセスが最初からやり直されます...「2 回目のパス」では、最初のルールは一致しなくなりますが(入力が であるためsomething.html)、2 番目のルールは一致するため、リダイレクトがトリガーされます。

(書き換えエンジンは、URLが変更されずに通過するまで、事実上「ループ」します。ディレクティブは、サーバ(ディレクトリ以外の) コンテキストでは、L書き換えエンジンによるパスが 1 回だけなので、フラグによってすべての処理が事実上停止されます。

ただし、Apache 2.4では、END代わりにフラグを使用して、書き換えエンジンによるすべての処理を停止することができます(ディレクトリコンテキスト)。例:

RewriteEngine On

RewriteRule ^something$ something.html [END]
RewriteRule ^(some|thing|any|stuff) /something [R=301,NC,L]

(注意:空間2 番目のルールの flags 引数にあります。これにより解析エラーが発生するため、これは質問の入力ミスであると想定します。

2 番目のルールの末尾の正規表現 (つまり.*/?$) は不要です。

Lリダイレクト(フラグ)とともにを使用するとR、 と同じですEND。すべての処理が停止します。

あなたの例では、このRewriteBaseディレクティブは不要です。

注意: 最初に 302 (一時的) リダイレクトでテストし、意図したとおりに動作することを確認してから 301 (永続的) に変更してください。301 はブラウザによって永続的にキャッシュされるため、テストが困難になる可能性があります。したがって、テストの前にブラウザ (および中間の) のキャッシュをクリアする必要があります。

でテストすると、https://htaccess.madewithlove.com/期待どおりに動作するはずです。

実際のサーバーとは異なり、MWL テスターは (実質的に) ルールを「1 回だけ」通過するだけなので、書き換え/リダイレクト ループを検出できません。


余談:通常、外部リダイレクトディレクティブは内部書き換えの前に配置する必要があります。ただし、自身にリダイレクトされる/somethingため、現在、2 つのディレクティブは、それらの順序に依存します。

関連情報