从htaccess中删除多个查询字符串参数

时间:2015-05-21 09:04:50

标签: regex .htaccess

我发现一些网站网址存在问题,我希望htaccess在删除一些查询字符串参数后重定向,例如:

http://www.mywebsite.com/archive?s=200&dis=default&opt=foo
http://www.mywebsite.com/archive?dis=foo&opt=baz

http://www.mywebsite.com/archive?type=default&format=rss
http://www.mywebsite.com/archive?pg=3&format=rss&type=default

我想保存除typeformatdisopt之外的所有参数,这些参数会导致404错误。我找到了删除单个参数的方法,但我仍然无法找到正则表达式或删除多个查询参数的内容。

到目前为止,这是我的代码:

RewriteCond %{REQUEST_URI} ^.*/archive
RewriteCond %{QUERY_STRING} ^(.*)&?view=[^&]+&?(.*)$ [OR]
RewriteCond %{QUERY_STRING} ^(.*)&?opt=[^&]+&?(.*)$ [OR]
RewriteCond %{QUERY_STRING} ^(.*)&?type=[^&]+&?(.*)$ [OR]
RewriteCond %{QUERY_STRING} ^(.*)&?format=[^&]+&?(.*)$
RewriteRule ^/?(.*)$ /$1?%1%2 [R=301,L]

哪个不起作用,因为它只删除一个参数并保存导致错误的其他参数。

P.S。正如您所看到的,它应该只适用于' archive'页面,但这不是问题:)

更新

这是我目前正在测试的网址:

http://www.mywebsite.com/archive?foo=0&force=0&format=feed&type=rss

我希望如此:

http://www.mywebsite.com/archive?foo=0&force=0

再 - 更新

通过使用collapsar的答案,服务器error_log显示了这一点:

Invalid command '<If', perhaps misspelled or defined by a module not included in the server configuration

1 个答案:

答案 0 :(得分:0)

<强>讨论

不幸的是,默认情况下,URL的查询字符串部分被排除在重写之外。 RewriteRule指令与查询字符串部分不匹配。任何查询字符串都需要在替换字符串中明确附加。

这意味着如果不诉诸RewriteCond指令就无法完成重写(fwiw,这就是为什么此答案的先前版本出错了)。

RewriteRuleRewriteCond标志相关联的OR个模式中的任何一个匹配后执行实际重写。这意味着不会对这些条件进行详尽的测试。

<强>解决方案

按如下方式调整规则集:

RewriteCond %{REQUEST_URI} ^.*/archive
RewriteCond %{QUERY_STRING} ^(.*?)([&?])format=[^&]+&?(.*)$
RewriteRule ^(.*)$ $1?%1%2%3

RewriteCond %{REQUEST_URI} ^.*/archive
RewriteCond %{QUERY_STRING} ^(.*?)([&?])opt=[^&]+&?(.*)$
RewriteRule ^(.*)$ $1?%1%2%3

RewriteCond %{REQUEST_URI} ^.*/archive
RewriteCond %{QUERY_STRING} ^(.*?)([&?])type=[^&]+&?(.*)$
RewriteRule ^(.*)$ $1?%1%2%3

RewriteCond %{REQUEST_URI} ^.*/archive
RewriteCond %{QUERY_STRING} ^(.*?)([&?])view=[^&]+&?(.*)$
RewriteRule ^(.*)$ $1?%1%2%3

RewriteCond %{REQUEST_URI} ^.*/archive
RewriteCond %{QUERY_STRING} ^(.*[?])breaktheloop=1(.*)$
RewriteRule .? - [S=1]
RewriteRule ^(.*)$ $1?breaktheloop=1 [QSA,R=301,L]
RewriteRule ^(.*)$ $1?%1%2 [L]

RewriteCond模式考虑到不正确转义的网址可能是查询字符串中某些参数的值。如果您不关心这一点,请删除非贪婪匹配修饰符(即使用^(.*)而不是^(.*?))。

<强>概要

与OP原始解决方案的不同之处在于:

  • 每个违规参数的个别替换
  • 包括替换模式中的参数分隔符
  • 为不正确转义的网址提供服务作为参数值
  • 个别重写(复制)规则,在应用任意数量的替换后触发重定向。保留已清理的查询字符串需要QSA标志。
  • breaktheloop参数,以打破重定向循环。

<强>文档

Apache httpd directive docs的相应部分是查找更详细信息的地方。