我正在尝试学习一些.htaccess
技巧。我遇到了RewriteBase
指令但无法使其正常工作。
我想知道这个指令具体是什么以及如何使用它。在StackOverflow和Apache文档中有一些关于RewriteBase
的讨论,但我仍然无法得到我的问题的明确答案。
有人可以向我展示一个简单但有效的例子,可以使用RewriteBase
吗?
答案 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
的正常处理是这样的:
/doc_root/one/.htaccess
,则生成的路径将为/two/three
。此过程导致相对于文档根目录的重写路径。
当存在RewriteBase
指令时,步骤1,2和3保持不变,只有步骤4更改。代替文档根目录,将删除包含.htaccess文件的目录的文件系统路径。然后RewriteBase
被放在前面。
示例:
https://example.com/one/two/three/file.txt
/var/doc_root
/var/doc_root/one/.htaccess
/var/other_location/
在htaccess文件中没有RewriteBase的情况下,将按以下方式处理:
/two/three/file.txt
/four/rewritten.txt
/var/do_root/one/four/rewritten.txt
one/four/rewritten.txt
在.htaccess文件中包含RewriteBase的情况下,此过程的处理方式为:
/two/three/file.txt
/four/rewritten.txt
/var/other_location/four/rewritten.txt