RewriteBase 仅适用于 relative 重写规则的目标。
-
像这样使用 RewriteBase...
RewriteBase /folder/
RewriteRule a\.html b.html
-
本质上与...相同
RewriteRule a\.html /folder/b.html
-
但是当 .htaccess 文件在 /folder/ 中时,这也指向同一个目标:
RewriteRule a\.html b.html
虽然文档暗示始终使用 RewriteBase,但 Apache 通常会正确检测到 DocumentRoot 下的路径,除非:
在这些情况下,您可能会发现需要指定 RewriteBase。
但是,由于它是一个令人困惑的指令,通常最好在重写目标中简单地指定绝对(也称为“根相对”)URI。阅读您的规则的其他开发人员会更容易掌握这些规则。
引用Jon Lin's excellent in-depth answer here:
在 htaccess 文件中,mod_rewrite 的工作方式类似于 <Directory> 或 <Location> 容器。 RewriteBase 用于提供相对路径基础。
例如,假设您有这样的文件夹结构:
DocumentRoot
|-- subdir1
`-- subdir2
`-- subsubdir
所以你可以访问:
-
http://example.com/(根)
-
http://example.com/subdir1 (subdir1)
-
http://example.com/subdir2 (subdir2)
-
http://example.com/subdir2/subsubdir(子目录)
通过RewriteRule 发送的 URI 与包含 htaccess 文件的目录相关。所以如果你有:
RewriteRule ^(.*)$ -
- 在根htaccess中,请求为
/a/b/c/d,则捕获的URI($1)为a/b/c/d。
- 如果规则在
subdir2 中并且请求是/subdir2/e/f/g,那么捕获的URI 是e/f/g。
- 如果规则在
subsubdir中,请求是/subdir2/subsubdir/x/y/z,那么捕获的URI是x/y/z。
规则所在的目录已从 URI 中剥离了该部分。重写基础对此没有影响,这只是每个目录的工作方式。
重写基础所做 的作用是为 规则的目标中的任何相对路径提供 URL 路径基础(不是 文件路径基础) 。所以说你有这个规则:
RewriteRule ^foo$ bar.php [L]
bar.php 是相对路径,而不是:
RewriteRule ^foo$ /bar.php [L]
/bar.php 是绝对路径。绝对路径将始终为“根”(在上面的目录结构中)。这意味着无论规则是否在“root”、“subdir1”、“subsubdir”等中,/bar.php 路径始终映射到http://example.com/bar.php。
但是另一个规则,相对路径,它基于规则所在的目录。所以如果
RewriteRule ^foo$ bar.php [L]
在“根”中,您转到http://example.com/foo,您将获得http://example.com/bar.php 的服务。但是,如果该规则位于“subdir1”目录中,并且您转到http://example.com/subdir1/foo,您将获得http://example.com/subdir1/bar.php。等等。这有时有效,有时无效,正如文档所说,它应该是相对路径的必需,但大多数时候它似乎有效。除非您正在重定向(使用R 标志,或者因为您的规则目标中有http://host 而隐含)。这意味着这条规则:
RewriteRule ^foo$ bar.php [L,R]
如果它在“subdir2”目录中,并且您转到 http://example.com/subdir2/foo,mod_rewrite 会将相对路径误认为是文件路径而不是 URL 路径,并且由于 R 标志,您将结束被重定向到类似的东西:http://example.com/var/www/localhost/htdocs/subdir1。这显然不是你想要的。
这就是 RewriteBase 的用武之地。该指令告诉 mod_rewrite 将什么附加到每个相对路径的开头。所以如果我有:
RewriteBase /blah/
RewriteRule ^foo$ bar.php [L]
在“subsubdir”中,转到http://example.com/subdir2/subsubdir/foo 实际上会为我服务http://example.com/blah/bar.php。 “bar.php”被添加到基数的末尾。在实践中,这个例子通常不是你想要的,因为你不能在同一个目录容器或 htaccess 文件中有多个碱基。
在大多数情况下,它是这样使用的:
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
这些规则在“subdir1”目录中的位置,并且
RewriteBase /subdir2/subsubdir/
RewriteRule ^foo$ bar.php [L]
将在“subsubdir”目录中。
这部分允许您使您的规则可移植,因此您可以将它们放在任何目录中,并且只需要更改基础而不是一堆规则。例如,如果您有:
RewriteEngine On
RewriteRule ^foo$ /subdir1/bar.php [L]
RewriteRule ^blah1$ /subdir1/blah.php?id=1 [L]
RewriteRule ^blah2$ /subdir1/blah2.php [L]
...
这样转到http://example.com/subdir1/foo 将服务http://example.com/subdir1/bar.php 等。假设您决定将所有这些文件和规则移动到“subsubdir”目录。与其将/subdir1/ 的每个实例都更改为/subdir2/subsubdir/,不如只使用一个基础:
RewriteEngine On
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
RewriteRule ^blah1$ blah.php?id=1 [L]
RewriteRule ^blah2$ blah2.php [L]
...
然后当您需要将这些文件和规则移动到另一个目录时,只需更改基础:
RewriteBase /subdir2/subsubdir/
就是这样。