剥离未列入白名单的URL中的任何参数

我需要去掉任何不在白名单中的参数,比如URL:

abc.com/somePage?phone=1234&stipAway=asd&fax=324&stripDown=disappear&zip=zip 

应该看:

 abc.com/somePage?phone=1234&fax=324&zip=zip 

相关问题: 如果使用的参数不在白名单中,则使用.htaccess文件重写URL

PS在前面提到的两个答案中,需要更复杂的解决scheme。 为了让我更容易理解,我将用更多的例子来说明:

 abc.com/somePage2?stripAway=asd&fax=324&stripDown=disappear&phone=1234&zip=zip 

应该看:

 abc.com/somePage2?fax=324&phone=1234&zip=zip 

 abc.com/somePage3?stripAway=asd&stripDown=disappear 

应该看:

 abc.com/somePage3 

如果清单是有序的,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) (负面(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 

以下应该为你工作:

 RewriteEngine On RewriteCond %{QUERY_STRING} ^(?:.*?&)?(phone=[^&]*)(?:.*?&)(fax=[^&]*)(?:.*?&)(zip=[^&]*) [NC] RewriteRule ^ %{REQUEST_URI}?%1%2%3 [L,R=302] 

PS:这是假设白名单参数出现在上面的顺序,即电话,传真,邮编