RewriteBase如何在.htaccess中工作

我在一些.htaccess示例中看到了这一点

 RewriteBase / 

它在function上与HTML的<base href="">似乎有些相似。

我相信它可能会自动将它的值预先写入RewriteRule语句的开头(可能没有前导斜杠)?

我无法让它正常工作。 我认为它的使用可以非常方便地进行网站的可移植性,因为我经常有一个与生产不同的开发服务器。 我目前的方法让我删除我的RewriteRule语句的部分。

任何人都可以简单地向我解释如何实现它?

谢谢

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

你可以使用RewriteBase为你的重写提供一个基础 。 考虑这个

 # 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在那里,可以使相对path脱离RewriteBase参数。

AFAIK,RewriteBase仅用于修复在.htaccess文件中运行mod_rewrite而不是在站点根目录的情况,并且为它正在运行的文件夹猜测错误的webpath(而不是文件系统path)。所以如果你在映射到http://example.com/myfolder的文件夹中的.htaccess中有一个RewriteRule,您可以使用:

 RewriteBase myfolder 

如果mod_rewrite工作不正常。

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

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

  • 使用RewriteBase像这样…

     RewriteBase /folder/ RewriteRule a\.html b.html 
  • 本质上是一样的… … –

     RewriteRule a\.html /folder/b.html 
  • 但是,当.htaccess文件在/文件夹/那么这也指向相同的目标:

     RewriteRule a\.html b.html 

尽pipe文档意味着总是使用RewriteBase ,但Apache通常会正确地检测DocumentRoot下的path,除非:

  • 您正在使用Alias指令

  • 您正在使用.htaccess重写规则来执行HTTPredirect (而不仅仅是静默重写)到相对URL

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

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


在这里引用Jon Lin的优秀深入的答案 :

在htaccess文件中,mod_rewrite与<Directory><Location>容器类似。 而RewriteBase则用来提供相对path的基础。

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

 DocumentRoot |-- subdir1 |-- subdir2 |-- subsubdir 

所以你可以访问:

  • http://example.com/ (根)
  • http://example.com/subdir1
  • http://example.com/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中删除。 重写基地对此没有影响,这只是每个目录的工作原理。

重写基地所做的是为规则目标中的任何相对path提供URLpath基础( 而不是文件path基础)。 所以说你有这个规则:

 RewriteRule ^foo$ bar.php [L] 

bar.php是一个相对path,而不是:

 RewriteRule ^foo$ /bar.php [L] 

/bar.php是绝对path。 绝对path将始终是“根”(在上面的目录结构中)。 这意味着无论规则是在“根”,“subdir1”,“subsubdir”等,/ /bar.phppath总是映射到http://example.com/bar.php

但是另一个规则是相对path,它是基于规则所在的目录

 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 。 等等。这个文件有时候可以起作用,有时不起作用,但是大多数情况下,它们都是相对path所必需的。 除了你正在redirect(使用R标志,或隐式,因为你的规则的目标中有http://host )。 这意味着这个规则:

 RewriteRule ^foo$ bar.php [L,R] 

如果它位于“subdir2”目录中,并且转到http://example.com/subdir2/foo ,则mod_rewrite会将相对path误认为文件path而不是URLpath,并且由于R标志,最终会被redirect到http://example.com/var/www/localhost/htdocs/subdir1 。 这显然不是你想要的。

这是RewriteBase进来的地方。该指令告诉mod_rewrite要追加到每个相对path的开头。 所以如果我有:

 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/ to /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/ 

就是这样。

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

最近,对于复杂的网站,我已经把它们拿出来了,因为它使得从testing中部署文件变得复杂一步。

我发现最清楚的解释不是在当前的2.4 apache文档,而是在2.0版本 。

 # /abc/def/.htaccess -- per-dir config file for directory /abc/def # Remember: /abc/def is the physical path of /xyz, ie, the server # has a 'Alias /xyz /abc/def' directive eg 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的文档继续给出“关于内部处理步骤的详细信息”。

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

当我开发时,它在一个文件夹内的不同域。 当我现场采访一个网站时,该文件夹不再存在。 使用RewriteBase允许我在两种环境中使用相同的.htaccess文件。

住时:

 RewriteBase / # RewriteBase /dev_folder/ 

开发时:

 # RewriteBase / RewriteBase /dev_folder/ 

这个命令可以明确地设置你的重写的基本URL。 如果您希望从您的域的根目录开始,那么在您的RewriteRule之前应包含以下行:

 RewriteBase / 

我相信这个Apache文档的摘录很好地补充了以前的答案:

除非满足以下任一条件,否则在每个目录(htaccess)上下文中的replace中使用相对path时,该指令是必需的:

  • 原始请求和replace位于DocumentRoot之下(而不是通过别名等其他方法可访问)。

  • 包含RewriteRule的目录的文件系统path(后缀为相对replace)在服务器上也是有效的(这很less见)。

如前所述,在其他情况下,缩短规则只是有用的。 此外,也如前所述,通过将htaccess文件放置在子目录中,可以实现同样的效果。