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

Posted

技术标签:

【中文标题】apache mod_rewrite:如何根据其他目录中的文件存在为同一目录添加不同的重写规则?【英文标题】:apache mod_rewrite: How to add different rewrite rules for same directory depending on file existence in other directory? 【发布时间】:2016-12-19 22:59:24 【问题描述】:

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

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

    直接向 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 ...等等

    对 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 $1 -f
RewriteRule ^abc/(.*?)$ $1

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

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

【问题讨论】:

【参考方案1】:

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

RewriteEngine on
Options FollowSymLinks
RewriteBase /

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

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

两个主要区别是:

使用[L] 标志表示在规则匹配后不应再考虑其他规则 - 这可能是为什么只有最后一条规则似乎有效的问题。 在条件和重写位置前加上%DOCUMENT_ROOT 以获得绝对路径。

【讨论】:

以上是关于apache mod_rewrite:如何根据其他目录中的文件存在为同一目录添加不同的重写规则?的主要内容,如果未能解决你的问题,请参考以下文章

Apache如何开启Mod_rewrite模块以及PHPWind伪静态(全伪)

mod_rewrite 在 apache 2.4 上无法正常工作

如何在 apache 上用 mod_rewrite 重写我的 url?

Ubuntu Apache配置及开启mod_rewrite模块

在Apache中使用mod_rewrite模块重写URL

如何将 mod_rewrite 与 Apache -> mod_jk -> tomcat 设置一起使用?