为什么RewriteCond需要此规则才能运行?

时间:2013-10-06 15:55:31

标签: .htaccess mod-rewrite

如果我有重写规则:

RewriteRule ([^?]*) /script.php?path=$1 [L,QSA]
除非我也有条件,否则它将返回500内部错误:

RewriteCond %{REQUEST_FILENAME} !-f

这是为什么?我的印象是条件并没有真正改变规则的运作方式,而是它们只是规则的例外。

2 个答案:

答案 0 :(得分:2)

-f测试给定参数是否为文件且是否存在(大小可能为0字节)。您收到500内部服务器错误的原因是因为重写引擎遍历所有规则,直到URI停止更改。例如,如果你只有这个:

RewriteRule ([^?]*) /script.php?path=$1 [L,QSA]

请求以/foobar的形式出现,URI为“foobar”

  1. “foobar”匹配([^?]*),URI被重写为“/script.php?path=foobar”
  2. 重写引擎循环
  3. “script.php”匹配([^?]*),URI被重写为“/script.php?path=script”
  4. 重写引擎循环
  5. 现在,如果添加条件:

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ([^?]*) /script.php?path=$1 [L,QSA]
    

    请求以/foobar URI为“foobar”

    进入
    1. “foobar”不是存在的文件,!-f为真
    2. “foobar”匹配([^?]*),URI被重写为“/script.php?path=foobar”
    3. 重写引擎循环
    4. “script.php” 存在的文件,!-f为false
    5. 条件为false,因此不应用规则。重写停止,生成的URI为“/script.php?path=foobar”

答案 1 :(得分:1)

这是你的规则:

RewriteRule ([^?]*) /script.php?path=$1 [L,QSA]

此处([^?]*)匹配除?之外的任何长度的0或更多长度。然后它将其重写为/script.php URI。再次注入生成的URI以进行评估。请注意,([^?]*)会再次匹配,因为non-?的0或更多,并再次应用规则。此循环继续,直到mod_rewrite超出递归限制(默认值= 10)。

现在你有了

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ([^?]*) /script.php?path=$1 [L,QSA]

RewriteCond %{REQUEST_FILENAME} !-f表示如果请求不是有效文件,则应用下一个RewriteRule

现在,在第一次重写后,目标URI /script.php是一个有效文件,RewriteCond这次失败,并且不会再次应用规则。

PS:此匹配模式([^?]*)将始终匹配所有URI模式,因为REQUEST_URI永远不会包含?

您的规则相当于:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ /script.php?path=$1 [L,QSA]