リストが整っていれば、anubhavaの答えは私のものよりもはるかに優れています. リストの順序が保証されていない場合は、次のルールを使用できます。Jon Lin がこの回答で使用している手法を使用しています。
RewriteCond %{QUERY_STRING} ^(.*&|)(?!(phone|fax|zip))[^=]+=
RewriteCond ##%{QUERY_STRING} (.*?)##(|.*&)(phone)=([^&]+)
RewriteCond %1&%3=%4##%{QUERY_STRING} (.*?)##(|.*&)(fax)=([^&]+)
RewriteCond %1&%3=%4##%{QUERY_STRING} (.*?)##(|.*&)(zip)=([^&]+)
RewriteRule ^(.*)$ $1?%3=%4%1 [R,L]
それで、それは何をしますか?最初の条件は、一致しないパラメーターが見つかった場合(phone|fax|zip)
(否定先読み) にのみ真になります。次の 3 つは、保持する各パラメーターをキャプチャし、カスタムセパレーターRewriteCond
の前にクエリ文字列を準備します。##
そのセパレーターがたまたまクエリ文字列に含まれていると、奇妙なことが起こります。
このアプローチの欠点は、これら 3 つのパラメーターのいずれかが存在しない場合、ルールが適用されないことです。私は個人的にこのホワイトリストをページ自体に配置し、.htaccess でフィルタリングしようとはしません。
編集: 一部のパラメーターがオプションの場合、次の怪物を使用できます。
RewriteCond %{QUERY_STRING} ^((.*?)&|)(?!(phone|fax|zip))[^=]+=[^&]+(&.*|)$
RewriteRule ^(.*)$ $1?%2%4 [R,E=Redir:1]
RewriteCond %{QUERY_STRING} ^&(.*)$
RewriteRule ^(.*)$ $1?%1 [R,E=Redir:1]
RewriteCond %{ENV:Redir} =1
RewriteRule ^ - [R,L]
基本的には、先読みのパラメータと一致しないパラメータが文字列にある場合、そのパラメータの前の部分とそのパラメータの後ろの部分を一致させ、クエリ文字列を再構築します。2 番目のルールは、最初のパラメーターが「ホワイトリストに登録」されていない (または単純に & で始まっている) 場合に、クエリ文字列全体を消費しないようにすることです。最後のルールは、リダイレクトの量を最小限に抑えることです。ホワイトリストに登録されていないパラメーターがリクエストに多すぎる場合、ブラウザーはエラーを表示することに注意してください (リダイレクト チェーンが検出されました)。
代わりに、ページ自体でフィルタリングすることをお勧めします。php では、次のコードのようなものになります。これにより、このホワイトリストの維持が容易になり、他の httpdeamon を使用することにした場合でも、すべてが壊れることはありません。
<?php
$whitelist = Array( 'phone', 'fax', 'zip' );
foreach( $_GET as $k => $v ) {
if( !in_array( $k, $whitelist ) )
unset( $_GET[$k] );
}
#And the same for $_POST and $_REQUEST