RewriteBase做了什么以及如何使用它?

时间:2014-01-25 07:08:21

标签: apache .htaccess mod-rewrite

我正在尝试学习一些.htaccess技巧。我遇到了RewriteBase指令但无法使其正常工作。

我想知道这个指令具体是什么以及如何使用它。在StackOverflow和Apache文档中有一些关于RewriteBase的讨论,但我仍然无法得到我的问题的明确答案。

有人可以向我展示一个简单但有效的例子,可以使用RewriteBase吗?

3 个答案:

答案 0 :(得分:87)

在htaccess文件中,mod_rewrite的工作方式类似于<Directory><Location>容器。 RewriteBase用于提供相对路径基础。

例如,假设你有这个文件夹结构:

root
 |-- subdir1
 |-- subdir2
       |-- subsubdir

所以你可以访问:

  • http://example.com/(root)
  • http://example.com/subdir1(subdir1)
  • http://example.com/subdir2(subdir2)
  • http://example.com/subdir2/subsubdir(subsubdir)

通过RewriteRule发送的URI是相对于目录的。所以如果你有:

RewriteRule ^(.*)$ - 
在根目录中

,请求为/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]

位于“root”中,您转到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/

就是这样。

答案 1 :(得分:2)

1行答案是: Rewritebase设置rewriterule arg2的基本路径

这就是字面意思。 (因此它的工作方式类似于html basehref,⨕ except it's useful,因为通常在URL重写的上下文中,默认基[.] 需要。)

如果您有多个重写,Rewritebase可以使维护更容易。 实际上,如果你只使用一行rewriterule,那么rewritebase几乎没用(因为你可以简单地重写基于url的URL)。

<小时/>的旁注

当然,您可以通过仅使用重写的绝对路径来忽略rewritebase 完全

<小时/> 相关

答案 2 :(得分:1)

RewriteBase允许您调整mod_rewrite自动加前缀到RewriteRule结果的路径。在.htaccess上下文中相对于包含该.htaccess文件的目录进行重写。 RewriteRule的直接结果仍然是相对于包含.htaccess文件的目录,但是mod_rewrite然后调整此结果,使其相对于文档根目录。 RewriteBase允许您修改此最后一步,从而允许您提供一个任意的 base 路径,该路径在RewriteRule的立即结果之前,而不是文档根目录下。

对我来说,理解RewriteBase指令的关键是当我意识到mod_rewrite将RewriteBase 应用于RewriteRules的结果,而不是应用于他们的论点。

在.htaccess文件的上下文中对RewriteRule的正常处理是这样的:

  1. 生成相对于包含.htaccess文件的目录的请求路径。例如,如果URI为https://www.example.com/one/two/three,并且.htaccess文件具有路径/doc_root/one/.htaccess,则生成的路径将为/two/three
  2. 然后RewriteRules从上面重写相对路径。
  3. 在上面生成的重写路径前面加上.htaccess文件的完整文件系统路径
  4. 从上面重写的路径的开头删除到文档根目录的路径。

此过程导致相对于文档根目录的重写路径。

当存在RewriteBase指令时,步骤1,2和3保持不变,只有步骤4更改。代替文档根目录,将删除包含.htaccess文件的目录的文件系统路径。然后RewriteBase被放在前面。

示例:

  • 请求-https://example.com/one/two/three/file.txt
  • 文档根-/var/doc_root
  • htaccess的位置-/var/doc_root/one/.htaccess
  • RewriteBase-/var/other_location/

在htaccess文件中没有RewriteBase的情况下,将按以下方式处理:

  1. 获取与htaccess相关的请求路径的一部分-/two/three/file.txt
  2. 进行重写-/four/rewritten.txt
  3. 将路径附加到.htaccess文件-/var/do_root/one/four/rewritten.txt
  4. 剥离文档根-one/four/rewritten.txt

在.htaccess文件中包含RewriteBase的情况下,此过程的处理方式为:

  1. 获取与htaccess相关的请求路径的一部分-/two/three/file.txt
  2. 进行重写-/four/rewritten.txt
  3. 添加RewriteBase-/var/other_location/four/rewritten.txt