如果該列表是爲了,anubhava的答案是比我好得多。如果列表不能保證按順序排列,則可以使用以下規則。它使用了Jon Lin uses in this answer的技術。
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)
(負向預見)不匹配的參數時才爲真。接下來的三個RewriteCond
捕獲您想要保留的每個參數,並在自定義##
分隔符之前準備查詢字符串。奇怪的事情將發生,如果該分隔符恰好在您的查詢字符串。
這種方法的缺點是,如果這三個參數中的一個不存在,則該規則將不適用。我會親自把這個白名單放在頁面本身,而不是通過.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]
基本上,如果參數字符串中不中先行匹配參數,它會匹配該參數前面的部分和該參數後面的部分並重新生成查詢字符串。第二個規則是,如果第一個參數不是「白名單」(或者它只是簡單地以&開頭),並且最後一條規則是試圖將重定向量保持在最小值,則防止吞噬整個查詢字符串。請注意,如果請求中沒有列入白名單的參數太多,瀏覽器將顯示錯誤(檢測到重定向鏈)。
相反,我會建議過濾頁面本身。在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
如果不是所有參數都存在,我已經用方法編輯了我的答案。我會建議在頁面本身上做這件事。 – Sumurai8
@Martins:對不起,我昨天不能參加這個問題。我相信會有一些純粹的.htaccess方法來做到這一點。我今天會嘗試。 – anubhava