我在一些.htaccess示例中看到过这种情况
RewriteBase /
它的功能似乎有点类似于HTML的<base href="">。
我相信它会自动把它的值放在RewriteRule语句的开头(可能是没有斜杠的语句)?
我无法让它正常工作。我认为它的使用对于站点的可移植性非常方便,因为我经常有一个与生产服务器不同的开发服务器。我当前的方法让我从RewriteRule语句中删除部分内容。
谁能简单地给我解释一下如何实现它?
谢谢
我在一些.htaccess示例中看到过这种情况
RewriteBase /
它的功能似乎有点类似于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
to
http://www.example.com/~new/page/
通过在那里设置RewriteBase,可以使相对路径脱离RewriteBase参数。
RewriteBase只在你只能把.htaccess放在你站点根目录的情况下有用。否则,你最好将不同的.htaccess文件放在站点的不同目录下,完全忽略RewriteBase指令。
最近,对于复杂的站点,我已经把它们去掉了,因为这使得从测试到实时的文件部署再复杂一步。
AFAIK, RewriteBase只用于修复mod_rewrite运行在。htaccess文件中而不是在站点的根目录下的情况,并且它为运行的文件夹猜测了错误的web路径(而不是文件系统路径)。所以如果你在一个。htaccess文件夹中有一个RewriteRule映射到http://example.com/myfolder,你可以使用:
RewriteBase myfolder
如果mod_rewrite不能正常工作。
试图用它来实现一些不寻常的东西,而不是解决这个问题,听起来像是一个非常混乱的配方。
当我开发时,它在一个文件夹中的另一个域中。当我启动一个网站时,这个文件夹就不存在了。使用RewriteBase可以让我在两个环境中使用相同的.htaccess文件。
当生活:
RewriteBase /
# RewriteBase /dev_folder/
当开发:
# RewriteBase /
RewriteBase /dev_folder/
我相信这段摘自Apache文档的摘录,很好地补充了前面的答案:
This directive is required when you use a relative path in a substitution in per-directory (htaccess) context unless either of the following conditions are true: The original request, and the substitution, are underneath the DocumentRoot (as opposed to reachable by other means, such as Alias). The filesystem path to the directory containing the RewriteRule, suffixed by the relative substitution is also valid as a URL path on the server (this is rare). As previously mentioned, in other contexts, it is only useful to make your rule shorter. Moreover, also as previously mentioned, you can achieve the same thing by placing the htaccess file in the subdirectory.
我发现最清楚的解释不在当前的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文档继续提供了“关于内部处理步骤的详细信息”。
经验教训:虽然我们需要熟悉“当前”,但我们可以在历史中找到珍宝。
RewriteBase只应用于相对重写规则的目标。
像这样使用RewriteBase… RewriteBase /文件夹/ 重写规则一个\.html b.html 本质上与…… 重写一个\.html /folder/b.html 但是当.htaccess文件在/folder/内时,它也指向相同的目标: 重写规则一个\.html b.html
虽然文档暗示总是使用RewriteBase,但Apache通常会正确地检测DocumentRoot下的路径,除非:
您正在使用Alias指令 您正在使用.htaccess重写规则来执行HTTP重定向(而不仅仅是静默重写)到相对url
在这些情况下,您可能会发现需要指定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 (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。 如果规则在子目录中,并且请求是/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是绝对路径。绝对路径总是“根”(在上面的目录结构中)。这意味着无论规则是否在“根目录”、“subdir1”、“subsubdir”等目录中,/bar.php路径总是映射到http://example.com/bar.php。
但另一个规则,相对路径,是基于规则所在的目录。因此,如果
RewriteRule ^foo$ bar.php [L]
is in the "root" and you go to http://example.com/foo, you get served http://example.com/bar.php. But if that rule is in the "subdir1" directory, and you go to http://example.com/subdir1/foo, you get served http://example.com/subdir1/bar.php. etc. This sometimes works and sometimes doesn't, as the documentation says, it's supposed to be required for relative paths, but most of the time it seems to work. Except when you are redirecting (using the R flag, or implicitly because you have http://host in your rule's target). That means this rule:
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文件中有多个base。
在大多数情况下,它是这样使用的:
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/,你可以只写一个base:
RewriteEngine On
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
RewriteRule ^blah1$ blah.php?id=1 [L]
RewriteRule ^blah2$ blah2.php [L]
...
然后当你需要把这些文件和规则移动到另一个目录时,只需要改变基:
RewriteBase /subdir2/subsubdir/
就是这样。