.htaccess 为什么需要重写此规则才能工作?

.htaccess 为什么需要重写此规则才能工作?,.htaccess,mod-rewrite,.htaccess,Mod Rewrite,如果我有重写规则: RewriteRule ([^?]*) /script.php?path=$1 [L,QSA] 它将返回500个内部错误,除非我也有以下条件: RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ([^?]*) /script.php?path=$1 [L,QSA] 为什么会这样?我的印象是,这些条件实际上并没有改变规则的工作方式,而是规则的例外情况。这是

如果我有重写规则:

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

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ([^?]*) /script.php?path=$1 [L,QSA]
为什么会这样?我的印象是,这些条件实际上并没有改变规则的工作方式,而是规则的例外情况。

这是你的规则:

RewriteRule ([^?]*) /script.php?path=$1 [L,QSA]
此处
([^?]*)
匹配0或更多长度的任何内容,但
除外。然后将其重写为
/script.php
URI。再次注入生成的URI进行评估。请注意,
([^?]*)
将再次匹配,因为它是0个或更多的
非-?
,并且规则将再次应用。这种循环一直持续到mod_rewrite超出递归限制(默认值=10)

现在当你有

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ([^?]*) /script.php?path=$1 [L,QSA]
RewriteCond%{REQUEST\u FILENAME}-f
表示如果请求不是针对有效文件,则应用下一个
重写规则

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

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

您的规则相当于:

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

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

RewriteRule ([^?]*) /script.php?path=$1 [L,QSA]
请求以
/foobar
的形式出现,URI为“foobar”

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

    RewriteCond %{REQUEST_FILENAME} !-f
    
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ([^?]*) /script.php?path=$1 [L,QSA]
    
    请求以
    /foobar
    的形式出现,URI为“foobar”

  • “foobar”不是一个存在的文件,
    -f
    为真
  • “foobar”匹配
    ([^?]*)
    ,URI被重写为“/script.php?path=foobar”
  • 重写引擎循环
  • “script.php”是一个存在的文件,
    -f
    为假
  • 条件为false,因此未应用规则。重写停止,结果URI为“/script.php?path=foobar”

  • 查看apache错误日志,看看实际的错误是什么,但很可能是一个无限进行的重定向循环。需要这个条件来确保重定向只在不是真实文件时发生(因此script.php不会无限重定向到自身)。感谢您逐步完成这个过程。我没意识到它在循环。所以,如果我只想排除单个脚本文件,我只需要有一个条件来测试该脚本的%{REQUEST_URI}?我的意图是匹配所有URI模式,但我没有意识到这有一个简单的方法。谢谢