apache - RewriteBase 的作用是什么以及如何使用它?

标签 apache .htaccess mod-rewrite

我正在尝试学习一些.htaccess技巧。我遇到了 RewriteBase 指令,但无法让它正常工作。

我想知道这个指令的具体作用以及如何使用它。 StackOverflow 和 Apache 文档中已经有一些关于 RewriteBase 的讨论,但我仍然无法得到我的问题的明确答案。

有人可以向我展示一个可以使用 RewriteBase 的简单但有效的示例吗?

最佳答案

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

例如,假设您有以下文件夹结构:

root
 |-- subdir1
 |-- subdir2
       |-- subsubdir

这样您就可以访问:

  • http://example.com/ (根)
  • http://example.com/subdir1 (子目录1)
  • http://example.com/subdir2 (子目录2)
  • http://example.com/subdir2/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/

就是这样。

关于apache - RewriteBase 的作用是什么以及如何使用它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21347768/

相关文章:

apache - Centos OS https 显示 apache2 默认页面

apache - 基于不同主机的 AuthUserFile 的不同路径

php - 带有查询字符串的 HTTP 缓存 URL

.htaccess - 重定向http=>https(非www)+ www https=>非www https(www 无证书)

.htaccess - 如何合并两个 .htaccess 重定向?

performance - Apache 上的 HTTPS;它会减慢 Apache 吗?

php - PATCH 请求 403 Forbidden

apache - Xampp + IIS 在同一台服务器上协同工作

node.js - htaccess Node 应用程序代理

php - htaccess 中的 mod_rewrite 是否有助于防止注入(inject)?