RewriteBase如何在.htaccess中工作


227

我已经在几个.htaccess例子中看到了

RewriteBase /

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

我相信它会自动将其值放在RewriteRule语句的开头(可能是那些没有前导斜线的语句)?

我无法使其正常工作。我认为它的使用可以非常方便地实现站点可移植性,因为我经常拥有与生产服务器不同的开发服务器。我当前的方法使我无法从RewriteRule语句中删除部分。

谁能简要向我解释如何实施?

谢谢



RewriteBase仅在目录或.htaccess上下文中起作用...请为提供的@SalmanPK链接引用上下文。
Eddie B

1
有关详细说明,请参见此答案。stackoverflow.com/a/2137593/292060
goodeye,


Answers:


102

用我自己的话说,阅读文档并进行实验后:

您可以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那里,您可以使相对路径脱离该RewriteBase参数。


10
“退出RewriteBase参数”-您的意思是rewriteRule参数吗?:)
Kissaki 2012年

1
我想澄清的htaccess的一些细节..没有一个ReWriteBase设置在htaccess的所有规则下面是什么它的声明?有没有办法将其重置,可以重置吗?
戴蒙2013年

3
@Kissaki:不,$1匹配项与带括号的RewriteRule模式匹配,但是替换的相对路径来自RewriteBase参数。因此,结果替换为/~new/$1/
MrWhite

3
@Damon:请参阅有关多个指令的此问题RewriteBase。简而言之,您不能有多个-我认为最后一个 RewriteBase指令会获胜,并会影响整个.htaccess文件。
怀特先生

24
-1; 这个答案似乎对其他人有所帮助,但是对我来说却是完全不透明的。我猜想“您可以RewriteBase用来提供重写的基础” -几乎只是单词的重新排列-但我不知道这种情况下的“基础” 什么,也不知道如果RewriteBase删除该行,您给出的示例将有所不同。转到手册我去...
Mark Amery

89

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重写规则来执行对相对URL的HTTP重定向(而不仅仅是静默重写)

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

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



引用林恩的出色深入解答

在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 (子目录)

通过a发送的URI RewriteRule相对于包含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中剥离了该部分。重写基础对此没有影响,这只是每个目录的工作方式。

重写库的作用是为规则target中的任何相对路径提供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/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/

就是这样。


对我来说,我很想念RewriteEngine On。例如,不需要1and1,但是在我的专用服务器上是必需的。
Portekoi

41

AFAIK,RewriteBase仅用于修复mod_rewrite在.htaccess不在站点根目录下的文件中运行并且猜测运行文件夹所在的Web路径(与文件系统路径相对)错误的情况。映射到http://example.com/myfolder您的文件夹中的.htaccess中的RewriteRule 可以使用:

RewriteBase myfolder

如果mod_rewrite无法正常工作。

尝试使用它来实现一些不寻常的事情,而不是解决此问题,听起来像是使自己非常困惑的秘诀。


2
是否需要以斜杠结尾?
Pacerier,2014年

@self,没有经过测试,在这里进行了不解释的说明:stackoverflow.com/a/11443194/632951
Pacerier,

23

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

最近,对于复杂的站点,我一直将它们删除,因为这使从测试到实时部署文件的部署又复杂了一步。


22
尽管这可能是个很好的建议,但这根本不能解决问题。因此,它应该是对问题的评论,没有受到(尽可能多的)支持,并且绝对不被接受为“答案”。
Kissaki'3

3
“最好不要将不同的.htaccess文件放在不同的目录中”-我不确定这是个好建议吗?在站点上遍布.htaccess文件,可能会使调试/维护成为一场噩梦。我会说最好在您网站的根目录中有一个.htaccess文件。
MrWhite

1
@ w3d还有一个时间问题:每次访问一个子目录时,都会解析多个.htaccess文件(从根目录到当前子目录)。有很多文件可以降低整体应答请求的速度,而不是在根单个文件,即使它包含了很多的规则..
Erenor拉巴斯

19

当我进行开发时,它位于文件夹内的其他域中。当我上线站点时,该文件夹不再存在。使用RewriteBase允许我在两种环境中使用相同的.htaccess文件。

直播时:

RewriteBase /
# RewriteBase /dev_folder/

开发时:

# RewriteBase /
RewriteBase /dev_folder/

4
我敢肯定这不会一直有效。例如,如果您%{REQUEST_URI}RewriteCond指令中使用该怎么办?
MrWhite

1
@ user1669830,如果只有一个重写器,则可以将基础添加到重写器stackoverflow.com/a/46541685/632951
Pacerier,2017年

18

我发现的最清楚的解释不是在当前的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, 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文档将继续提供“有关内部处理步骤的详细信息”。

经验教训:尽管我们需要熟悉“最新”知识,但可以在史册中找到宝石。



2

我相信来自Apache文档的摘录很好地补充了先前的答案:

当在每个目录(htaccess)上下文中的替换中使用相对路径时,除非满足以下两个条件之一,否则此指令是必需的:

  • 原始请求和替代请求位于DocumentRoot(与其他方法(例如Alias)可访问的对象)相比之下。

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.