次のように、SEO に適した URL に書き換える必要があるすべてのクエリ文字列があります。
RewriteRule ^item_([0-9]+)/$ database.php?type=product&id=$1 [L]
RewriteRule ^post_([0-9]+)/$ articles.php?id=$1 [L]
... and so on
しかし、SEO とセキュリティの両方の理由から、item_123/?foo=barまたはdatabase.php?foo=barまたはpost_123/?type=product&id=321などの他のクエリ文字列を削除したいと考えています。
明らかに明らかな配置の解決策
RewriteCond %{QUERY_STRING} (.+)
RewriteRule (.*) http://www.example.com/$1? [R=301,L]
.htaccess の最後で、以前に Bean が処理されず、[L] タグで停止されたすべてのものを処理するために、実際には元の RewriteRule が壊れ、item_123/がパラメーターなしの空のdatabase.phpにリダイレクトされます。
%{REQUEST_URI} と %{QUERY_STRING} のすべてのペアの例外を明示的に書き留めることなく、以前に mod_rewrite されたものを除くすべてのクエリ文字列を削除することは可能ですか?
編集:
ソリューション A
# You do not need this whole block if you're running Apache v2.3.9+
RequestHeader set SOME-FANCY-NAME-FOR-THE-HEADER-AS-DESCRIBED-IN-THE-ABOVE-LINK 1 env=END
RewriteCond %{HTTP:SOME-FANCY-NAME-FOR-THE-HEADER-AS-DESCRIBED-IN-THE-ABOVE-LINK} =1 [NV]
RewriteRule .* - [L]
この[END]
フラグは Apache v2.3.9+ でのみ機能するため、この動作をエミュレートする回避策を使用しました。
# Replace [L,E=END:1] with [END] if running Apache v2.3.9+
RewriteCond %{THE_REQUEST} ^GET\ [^?]+$
RewriteRule ^item_([0-9]+)/$ database.php?type=product&id=$1 [L,E=END:1]
?
最初に THE_REQUEST のいずれかを制限するだけでは、item_123/?foo=bar
パターンの重複ページが見つかりません (404)。この[L,E=END:1]
フラグは、mod_rewrite に現在の反復を停止して反復するように指示します。次の反復がトリガーRewriteRule .* - [L]
され、その後の潜在的なループに到達するのをブロックします。フラグがサポートされていれば、[END]
すぐに停止します。
RewriteCond %{QUERY_STRING} type=product
RewriteCond %{QUERY_STRING} id=([0-9]+)
RewriteRule ^database\.php$ http://www.example.com/item_%1/? [R=301,L]
これにより、クエリ内の意味不明なパラメータに関係なく、侵害された可能性のあるパターンの重複ページがdatabase.php?type=product&foo=bar&id=123
正しい URL にリダイレクト (301) されます。正しい URL に到達すると、ループやエラー 500 を発生させることなくそこで停止します。
# If page is accessible without parameters
RewriteCond %{THE_REQUEST} ^GET\ [^?]+$
RewriteRule ^catalog/$ database.php [L,E=END:1]
RewriteCond %{THE_REQUEST} ^GET\ [^?]+\?
RewriteRule ^database\.php$ http://www.example.com/catalog/? [R=301,L]
?type
ページがおよび&type
上記のようなパラメーターなしでアクセス可能であるが、database.php?foo=bar
またはとしてアクセスされる場合、クエリ文字列なしdatabase.php?
で にリダイレクト (301) されます。catalog/
ここでも、パターンのページはcatalog/?foo=bar
見つかりません (404)。
# If page is not accessible without parameters
RewriteCond %{THE_REQUEST} ^GET\ [^?]+\?
RewriteRule ^database(\.php|/)?$ database.php [L,E=END:1]
パラメーターなしでページにアクセスできない場合は、書き換えを強制的に停止し (たとえば、にanyotherfile.php
書き換えた場合に後で不要なリダイレクトを回避するためanyotherfile/
)、有効なパラメーターが渡されていないことを認識したら、ページ自体に 404 ヘッダーを送信させることができます。
ソリューション A+B
承認されたソリューションのコードはそれ自体で正しいものですが、私のバージョンでは、他の多くの不正なパターンに一致するように書き換えを拡張しています。
上記のすべてのコードの後に受け入れられたソリューションからコードを追加すると、(以前は)item_123/?foo=bar
とパターンの見つからなかったリンクがキャプチャされ、クエリ文字列なしで正しい URLにcatalog/?foo=bar
リダイレクト (301) されます。ユーザーは、RSS アグリゲーターなどによって変更されたリンクをたどっても、目的の場所にたどり着くことができるため、これは理にかなっています。上記のコードの代わりにusing を使用するように変更すると、末尾の疑問符も削除されます.item_123/
catalog/
%{QUERY_STRING} (.+)
%{THE_REQUEST} ^GET\ [.?]+\?
%{THE_REQUEST} ^GET\ [^?]+$
%{QUERY_STRING} ^$
item_123/?
RewriteCond %{THE_REQUEST} ^GET\ [^?]+\?
RewriteRule (.*) http://www.example.com/$1? [R=301,L]