RewriteBase如何在.htaccess中工作

时间:2009-04-01 04:45:42

标签: .htaccess mod-rewrite

我在一些.htaccess示例

中看到了这一点
RewriteBase /

它的功能似乎与HTML的<base href="">有些相似。

我相信它可能会自动将其值添加到RewriteRule语句的开头(可能是没有前导斜杠的语句)?

我无法让它正常工作。我认为它的使用对于站点可移植性非常方便,因为我经常有一个与生产服务器不同的开发服务器。我当前的方法让我删除了RewriteRule语句中的部分内容。

有人能简单地向我解释如何实施它吗?

由于

8 个答案:

答案 0 :(得分:96)

用我自己的话来说,在阅读完文档和试验之后:

您可以使用RewriteBase为重写提供 base 。考虑一下这个

# invoke rewrite engine
    RewriteEngine On
    RewriteBase /~new/

# add trailing slash if missing
    rewriteRule ^(([a-z0-9\-]+/)*[a-z0-9\-]+)$ $1/ [NC,R=301,L]

这是我用来确保URL有一个尾部斜杠的真实规则。这将转换

http://www.example.com/~new/page

http://www.example.com/~new/page/

通过RewriteBase,您可以使相对路径脱离RewriteBase参数。

答案 1 :(得分:70)

RewriteBase仅适用于 相对 重写规则的 目标

  • 像这样使用RewriteBase ......

    RewriteBase /folder/
    RewriteRule a\.html b.html
    
  • 与...基本相同。

    RewriteRule a\.html /folder/b.html
    
  • 但当.htaccess文件位于/folder/内时,这也指向同一目标:

    RewriteRule a\.html b.html
    

虽然文档暗示始终使用RewriteBase,但Apache通常会对DocumentRoot下的路径进行正确检测,除非:

  • 您正在使用Alias指令

  • 您正在使用.htaccess重写规则来执行 HTTP重定向(而不仅仅是静默重写)相对网址

在这些情况下,您可能会发现需要指定RewriteBase。

但是,由于它是一个令人困惑的指令,通常最好只在重写目标中指定绝对(也称为“根相对”)URI。阅读规则的其他开发人员将更容易掌握这些规则。



引自Jon Lin's excellent in-depth answer here

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

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

DocumentRoot
|-- 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相对于包含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]

位于“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/

就是这样。

答案 2 :(得分:41)

AFAIK,RewriteBase仅用于修复mod_rewrite在不在站点根目录的.htaccess文件中运行的情况,并且它猜测文件夹的错误Web路径(而不是文件系统路径)因此,如果您在映射到http://example.com/myfolder的文件夹中的.htaccess中有RewriteRule,则可以使用:

RewriteBase myfolder

如果mod_rewrite无法正常工作。

尝试使用它来实现一些不寻常的东西,而不是解决这个问题听起来像是一个让人感到困惑的秘诀。

答案 3 :(得分:23)

RewriteBase仅在您只能将.htaccess放在站点根目录的情况下才有用。否则,您可能最好将不同的.htaccess文件放在站点的不同目录中,并完全省略RewriteBase指令。

最近,对于复杂的网站,我一直把它们拿出来,因为它使得从测试部署文件变得更加复杂。

答案 4 :(得分:19)

开发时,它位于文件夹中的其他域中。当我现场直播时,该文件夹不再存在。使用RewriteBase允许我在两个环境中使用相同的.htaccess文件。

活着时:

RewriteBase /
# RewriteBase /dev_folder/

开发时:

# RewriteBase /
RewriteBase /dev_folder/

答案 5 :(得分:18)

我发现的最清晰的解释不在当前的2.4 apache文档中,而是在version 2.0中。

#  /abc/def/.htaccess -- per-dir config file for directory /abc/def
#  Remember: /abc/def is the physical path of /xyz, i.e., the server
#            has a 'Alias /xyz /abc/def' directive e.g.

RewriteEngine On

#  let the server know that we were reached via /xyz and not
#  via the physical path prefix /abc/def
RewriteBase   /xyz

它是如何工作的?对于你的apache黑客,这个2.0文档继续提供“关于内部处理步骤的详细信息。”

获得的经验:虽然我们需要熟悉“当前”,但宝石可以在年鉴中找到。

答案 6 :(得分:3)

此命令可以显式设置重写的基本URL。如果您希望从域的根目录开始,则应在RewriteRule之前包含以下行:

RewriteBase /

答案 7 :(得分:2)

我相信这篇摘自Apache文档的内容很好地补充了之前的答案:

  

当您在a中使用相对路径时,此指令是必需的   在每个目录(htaccess)上下文中替换,除非其中任何一个   以下条件属实:

     
      
  • 原始请求和替换位于DocumentRoot下方(而不是通过其他方式,例如Alias可以访问)。

  •   
  • 包含RewriteRule的目录的文件系统路径(以相对替换为后缀)也可用作URL路径   服务器(这很少见)。

  •   
     

如前所述,在其他情况下,它只是有用的   你的规则更短。而且,如前所述,你也可以   通过将htaccess文件放入其中来实现相同的功能   子目录。