apache mod_rewrite:如何根据其他目录中的文件存在为同一目录添加不同的重写规则?

apache mod_rewrite: How to add different rewrite rules for same directory depending on file existence in other directory?

我目前在为具有 mod_rewrite 的 Apache 2.2 服务器的 .htaccess 文件中配置重写规则时遇到了一些麻烦。这是我想做的事情的总体思路:

假设服务器域是example.com/,所有对example.com/abc/的请求和该目录下的路径都将被重写。有两种情况:

  1. 直接请求 example.com/abc/ 或 example.com/abc/index.php 应成为请求 example.com/index.php 带有一个额外的参数来指示请求的原始目录。举几个例子:

    • example.com/abc/ ==> example.com/abc/index.php?directory=abc
    • example.com/abc/?foo=1&bar=2 ==> example.com/abc/index.php?directory=abc&foo=1&bar=2
    • example.com/abc/?a=b&c=d ==> example.com/abc/index.php?directory=abc&a=b&c=d
    • ...等等
  2. example.com/abc/ 中的文件请求应成为 example.com/ 中文件的请求,如果这些文件存在于那里。参数表示当前目录。举几个例子:

    • example.com/abc/image.png ==> example.com/image.png(如果后面的文件存在)
    • example.com/abc/sub/file.css ==> example.com/sub/file.css(如果后面的文件存在)
    • example.com/abc/foo/bar/baz/name.js ==> example.com/foo/bar/baz/name.js(如果后面的文件存在)
    • ...等等。

我的 .htaccess 的内容目前看起来类似于:

RewriteEngine on
Options FollowSymLinks
RewriteBase /

# rule for files in abc/: map to files in root directory
RewriteCond  -f
RewriteRule ^abc/(.*?)$ 

# rule for abc/index.php: map to index.php?directory=abc&...
RewriteCond  !-f
RewriteRule ^abc/(.*?)$ index.php?directory=abc& [QSA]

后面的规则似乎有效,请求示例。com/abc/index.php 按预期重写。但是,这不适用于 abc/ 目录中的文件。 对我在这里做错了什么以及如何解决该问题的任何提示表示赞赏。必须对 .htaccess 应用哪些更改才能使事情如描述的那样工作?

我找到了可行的解决方案:

RewriteEngine on
Options FollowSymLinks
RewriteBase /

# rule for file in abc/: map them to files in document root
RewriteCond %{DOCUMENT_ROOT}/ -f
RewriteRule ^abc/(.*?)$ %{DOCUMENT_ROOT}/ [L]

# rule for abc/index.php: map to index.php?directory=abc&...
RewriteRule ^abc/(.*?)$ %{DOCUMENT_ROOT}/index.php?directory=abc& [QSA,L]

两个主要区别是:

  • 使用 [L] 标志指示规则匹配后不应考虑进一步的规则 - 这可能就是为什么只有最后一条规则似乎有效的问题。
  • 条件中的前缀位置和重写位置 %{DOCUMENT_ROOT} 以获得绝对路径。