重写规则捕获所有+ QSA无法正常工作

时间:2015-11-30 01:40:07

标签: php apache .htaccess mod-rewrite

我正试图在用户登陆我网站的根目录时显示默认视图(主页),这就是我使用的

RewriteCond %{REQUEST_URI} ^/$
Rewriterule ^(.*)$ index.php?view=home [L]

根据这个其他规则,我试图抓住所有有变量的东西(因为我的所有路径都被重写了,我应该永远不会有像mydomain.com?somevar = true这样的东西,所以我寻找&或=或? ),并将查询字符串传递给页面

RewriteCond %{REQUEST_URI} ^([\&|\=|\?]+)$
RewriteRule ^(.*)$ badstuff.php [L,QSA]

我不明白的是mydomain.com/?test=true被重定向到index.php?view = home而不是去badstuff.php

我做错了什么?如果我评论第一条cond +规则,第二条规则永远不会匹配......

谢谢你。

修改:添加了更多规则以便更好地理解。忘了提, Apache 2.4 这就是我现在所拥有的

#standard views
Rewriterule ^home$ index.php?view=home [L] (works)
Rewriterule ^about$ index.php?view=about [L] (works)

#default view
RewriteCond %{REQUEST_URI} ^/$
Rewriterule ^(.*)$ index.php?view=home [L] (works)

#bad stuff
Rewriterule ^[\?=&]$ badstuff.php [L,QSA] (doesnt work)

1 个答案:

答案 0 :(得分:0)

这里的主要问题是您正在尝试匹配REQUEST_URI内的查询字符串,但该变量不包含查询字符串。

From the Apache docs:

  

REQUEST_URI   请求的URI的路径组件,例如" /index.html"。这显然排除了查询字符串,该字符串可用作名为QUERY_STRING的自己的变量。

相反,您只需要匹配%{QUERY_STRING}内的任何非空字符,并且必须将该规则放在匹配/的规则之前,因为/?abc=123仍会匹配/ 1}}规则。

# Match a non-empty query string (. is any one character)
RewriteCond %{QUERY_STRING} .
# Don't apply this if the view= has already been applied
RewriteCond %{QUERY_STRING} !view=
# Rewrite to badstuff.php and append the params.
RewriteRule ^.*$ badstuff.php [L,QSA]

# Then rewrite the root
RewriteCond %{REQUEST_URI} ^/$
Rewriterule ^(.*)$ index.php?view=home [L]

更好的版本:

我会稍微简化您的第一条规则以消除RewriteCond,因为只有路径需要RewriteRule匹配。我还删除了所有()个捕获组,因为您实际上并未使用它们捕获的值。

RewriteCond %{QUERY_STRING} .
RewriteCond %{QUERY_STRING} !view=
# Rewrite to badstuff.php and append the params.
RewriteRule .* badstuff.php [L,QSA]

# Match a non-empty path into view=
RewriteRule ^([^/]+)$ index.php?view=$1 [L]
# Then a simpler rule that matches ^$ (no path)
RewriteRule ^$ index.php?view=home [L]

如果您在VirtualHost配置而不是.htaccess中应用此功能,RewriteRule将包含前导/,因此您需要使用:

RewriteRule ^/$ index.php?view=home [L]

但{。{1}}在.htaccess中使用的

现在,如果/过于宽泛地阻止查询字符串匹配,您可以在!view=中使用匹配查询参数。

THE_REQUEST