1

如果我有重写规则:

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

除非我也有以下条件,否则它将返回 500 内部错误:

RewriteCond %{REQUEST_FILENAME} !-f

为什么是这样?我的印象是这些条件实际上并没有改变规则的工作方式,而是它们只是规则的例外。

4

2 回答 2

2

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

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

并且请求进来,因为/foobarURI 是“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是假的
  5. 条件为假,因此不应用规则。重写停止,生成的 URI 是“/script.php?path=foobar”
于 2013-10-06T16:27:56.877 回答
1

这是你的规则:

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

这里([^?]*)匹配 0 或更多长度的任何内容,但?. 然后将其重写为/script.phpURI。再次注入生成的 URI 以进行评估。请注意,([^?]*)它将再次匹配,因为它有 0 个或多个non-?并且再次应用规则。这个循环一直持续到 mod_rewrite 用完递归限制(默认 = 10)。

现在当你有

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

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

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

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

您的规则相当于:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ /script.php?path=$1 [L,QSA]
于 2013-10-06T16:25:19.910 回答