【问题标题】:Set RewriteBase to the current folder path dynamically将 RewriteBase 动态设置为当前文件夹路径
【发布时间】:2014-01-30 11:41:27
【问题描述】:

有没有办法将 RewriteBase 设置为相对于主机根目录的路径当前文件夹(.htaccess 文件所在的文件夹)?

我有一个 CMS,如果我将它移动到主机中的目录,它就不起作用,除非我将 RewriteBase 设置为相对于主机根目录的目录路径。我希望我的 CMS 只使用复制和粘贴,而不更改 htaccess 中的任何代码。

更新:

例如:

webroot

 - sub_directory
 - cms
 - .htaccess

在这种情况下,我应该在 htaccess 中写:RewriteBase /

如果我将 htaccess 移动到 sub_directory 中,我应该将 RewriteBase 更改为:

RewriteBase /sub_directory/

所以我想要类似的东西

RewriteBase /%{current_folder}/

【问题讨论】:

  • 那是相对于文档根目录的?
  • 查看更新@Sumurai8

标签: regex apache .htaccess mod-rewrite url-rewriting


【解决方案1】:

这是一种可以在环境变量中获取RewriteBase 的方法,然后您可以在其他重写规则中使用它:

RewriteCond %{REQUEST_URI}::$1 ^(.*?/)(.*)::\2$
RewriteRule ^(.*)$ - [E=BASE:%1]

那么你可以在你的规则中使用%{ENV:BASE}来表示RewriteBase,即:

#redirect in-existent files/calls to index.php
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteRule . %{ENV:BASE}/index.php [L]

说明:

此规则通过将REQUEST_URIRewriteRule 看到的URL 路径进行比较,即REQUEST_URI 去掉了前导RewriteBase。区别在于RewriteBase 被放入%{ENV:BASE}

  • RewriteCond 中,LHS(测试字符串)可以使用反向引用变量,例如$1$2%1%2 等,但 RHS 端即条件字符串 不能使用 这些 $1$2%1%2 变量。
  • 在 RHS 条件部分中,我们可以使用的唯一反向引用是内部反向引用,即我们在此条件本身中捕获的组。它们用\1\2等表示。
  • RewriteCond 第一个捕获的组中是(.*?/)。它将由内部反向引用 \1 表示。
  • 您可以看出,这条规则基本上是通过比较%{REQUEST_URI}$1 动态找到RewriteBase%{REQUEST_URI} 的示例将是 /directory/foobar.php$1 的示例对于同一示例 URI 将是 foobar.php^(.*?/)(.*)::\2$ 将差异放在第一个捕获组 %1\1 中。对于我们的示例,它将使用值/directory/ 填充%1\1,该值稍后用于在E=BASE:%1 中设置环境变量%{ENV:BASE}

【讨论】:

  • 能否更改这两个命令以匹配包含多个正斜杠的 URL?例如,这将不起作用:/directory/a///b/c/(注意 a 后面的 3 个斜杠)
  • 是的,使用重定向规则所有多个斜杠应首先修剪为单个/
  • 今天,五年多之后,你可能挽救了我的理智。谢谢!这开始吞噬我的灵魂!
【解决方案2】:

我认为接受的解决方案对我不起作用,但确实如此:https://web.archive.org/web/20180401034514/http://www.zeilenwechsel.de/it/articles/8/Using-mod_rewrite-in-.htaccess-files-without-knowing-the-RewriteBase.html

长话短说:

RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond $0#%{REQUEST_URI} ([^#]*)#(.*)\1$
RewriteRule ^.*$ %2index.php [QSA,L]

【讨论】:

  • 伙计,你救了我的命,这件作品 100% 有效,而且它不像鞋面那样短。如果我能竖起大拇指。
  • 我已将链接更改为使用 archive.org 。未来打样:castledragmire.com/misc/HTAccessPost.png
【解决方案3】:

anubhava's answerJon Lin's 的基础上,这是我自己想出的(尚未在生产中使用过,也没有进行过广泛的测试)。

让我们使用这个示例 URL,其中 .htaccess 在 current_folder 中:

http://localhost/path_to/current_folder/misc/subdir/file.xyz

文件系统:/var/www/webroot/path_to/current_folder/.htaccess

Options +FollowSymLinks
RewriteEngine On
RewriteBase /

RewriteCond %{ENV:SUBPATH} ^$  # Check if variable is empty. If it is, process the next rule to set it.
RewriteRule ^(.*)$ - [ENV=SUBPATH:$1]
# SUBPATH is set to 'misc/subdir/file.xyz'

RewriteCond %{ENV:CWD} ^$
RewriteCond %{ENV:SUBPATH}::%{REQUEST_URI} ^(.*)::(.*?)\1$
RewriteRule ^ - [ENV=CWD:%2]
# CWD is set to '/path_to/current_folder/'

RewriteCond %{ENV:FILENAME} ^$
RewriteCond %{REQUEST_URI} ^.*/(.*)$
RewriteRule ^ - [ENV=FILENAME:%1]
# FILENAME is set to 'file.xyz'

# Check if /var/www/webroot/path_to/current_folder/misc/subdir/file.xyz exists.
# -f checks if a file exists, -d checks for a directory.
# If it exists, rewrite to /path_to/current_folder/misc/subdir/file.xyz and stop processing rules.
RewriteCond %{ENV:SUBPATH} ^.+$  # Ensure SUBPATH is not empty
RewriteCond %{DOCUMENT_ROOT}%{ENV:CWD}%{ENV:SUBPATH} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{ENV:CWD}%{ENV:SUBPATH} -d
RewriteRule ^.*$ %{ENV:CWD}%{ENV:SUBPATH} [END]

# Check if /var/www/webroot/path_to/current_folder/file.xyz exists.
# If it exists, rewrite to /path_to/current_folder/file.xyz and stop processing rules.
RewriteCond %{ENV:FILENAME} ^.+$
RewriteCond %{DOCUMENT_ROOT}%{ENV:CWD}%{ENV:FILENAME} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{ENV:CWD}%{ENV:FILENAME} -d
RewriteRule ^.*$ %{ENV:CWD}%{ENV:FILENAME} [END]

# Else, rewrite to /path_to/current_folder/index.html and stop processing rules.
RewriteRule ^.*$ %{ENV:CWD}index.html [END]

您可以通过在 apache 中的 httpd.conf 中使用 LogLevel alert rewrite:trace6,然后查看您的 error.log,来查看自己发生的事情的详细信息。

这里对以下两行进行了更多说明,我仍然觉得有些混乱。

RewriteCond %{ENV:SUBPATH}::%{REQUEST_URI} ^(.*)::(.*?)\1$
RewriteRule ^ - [ENV=CWD:%2]

首先,双冒号:: 不是任何类型的运算符;它只是一个任意分隔符。 RewriteCond 将 TestString %{ENV:SUBPATH}::%{REQUEST_URI} 扩展为以下内容:

misc/subdir/file.xyz::/path_to/current_folder/misc/subdir/file.xyz

然后是我们的 CondPattern ^(.*)::(.*?)\1$:

  1. ^(.*):: 匹配 misc/subdir/file.xyz::
  2. \1 是第一个捕获组,misc/subdir/file.xyz
  3. (.*?)\1$ 变为 (.*?)misc/subdir/file.xyz$
  4. 因此,我们的第二个捕获组(.*?) 匹配剩余的/path_to/current_folder/

而我们的RewriteRuleCWD 设置为%2,这是CondPattern 的第二个捕获组。

【讨论】:

    【解决方案4】:

    如果你在 htaccess 中有RewriteBase 命令,你可以评论它,然后它会自动解析到那个目录。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-01
      • 2018-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-21
      • 1970-01-01
      相关资源
      最近更新 更多