使用 mod_rewrite 重写规则将子目录重定向到另一个子目录
Redirect subdirectory to another subdirectory with mod_rewrite rewriterules
在子目录 alpha
内的 .htaccess
中(从根向下的几个目录:http://domain.com/subsite/alpha/.htaccess
)我想捕获对文件的所有请求:
http://domain.com/subsite/alpha/images/
并将他们重定向到:
http://domain.com/subsite/alpha/img/
我的 .htaccess
看起来像这样:
RewriteRule ^images/(.*)$ %{REQUEST_URI}/\.\./\.\./img/ [R=302,NC,L]
这仅在 /images
中没有其他目录时有效。我可以让它像这样从 root 开始工作
RewriteRule ^images/(.*)$ /subsite/alpha/img/ [R=302,NC,L]
但我必须手动将其从 alpha
更新为 beta
、preprod
等
基本上,我需要一种方法来隔离 ^
和 images/
之间的所有内容。我尝试了一些变体:
RewriteRule ^(.*)images/(.*)$ //img/ [R=302,NC,L]
RewriteRule ^(.*)images/(.*)$ ^/img/ [R=302,NC,L]
但它不起作用,因为 .htaccess
在 alpha
中并且不知道它和 root 之间的内容。因此在上面,
不是 /subsite/alpha
而是 /alpha
和 images/
.
之间的任何东西
您可以使用 RewriteBase
并使用相对路径:
RewriteEngine On
RewriteBase /subsite/alpha/
RewriteRule ^images/(.*)$ img/ [R=302,NC,L]
否则如果您想避免使用 RewriteBase
然后使用此规则生成动态 RewriteBase
:
RewriteEngine On
RewriteCond [=11=]#%{REQUEST_URI} ^([^#]*)#(.*)$
RewriteRule ^.*$ - [E=BASE:%2]
RewriteRule ^(.*?/)?images/(.*)$ %{ENV:BASE}img/ [R=302,NC,L,NE]
动态 RewriteBase
的工作原理:
- 它将
REQUEST_URI
变量(完整路径)与RewriteRule
匹配的URI(相对于当前路径)进行比较,并在%{ENV:BASE}
变量中得到差异。
- 您可以在
RewriteCond
中使用从 RewriteRule
捕获的 [=19=]
,因为 mod_rewrite
实际上 向后处理规则集 。它从 RewriteRule
中的模式开始,如果匹配,则继续检查一个或多个 RewriteCond
.
- 因此,正如您在
RewriteCond
中看到的那样,LHS(测试字符串)可以使用反向引用变量,例如</code>、<code>
或 %1
、%2
等,但 RHS 端即条件字符串 不能使用 这些 </code>、<code>
或 %1
、%2
个变量。
- 在 RHS 条件部分中,我们可以使用的唯一反向引用是 内部反向引用,即我们在此条件本身中捕获的组。它们被表示为
</code>、<code>
等
- 在您的
RewriteCond
中,第一个捕获的组是 ([^#]*)
。它将由内部反向引用 `\1. 表示
- 正如您所指出的,这条规则基本上是通过比较
%{REQUEST_URI}
和 [=19=]
动态地找到 RewriteBase
。 %{REQUEST_URI}
的示例将是 /directory/foobar.php
,对于同一示例 URI,[=19=]
的示例将是 foobar.php
。 ^([^#]*)#(.*)$
将差异放在第二个捕获组 %2
或 </code> 中。这里 t 将使用值 <code>/directory/
填充 %2
或 </code>,稍后在设置环境变量 <code>%{ENV:BASE}
时使用,即 E=BASE:%2
.
在子目录 alpha
内的 .htaccess
中(从根向下的几个目录:http://domain.com/subsite/alpha/.htaccess
)我想捕获对文件的所有请求:
http://domain.com/subsite/alpha/images/
并将他们重定向到:
http://domain.com/subsite/alpha/img/
我的 .htaccess
看起来像这样:
RewriteRule ^images/(.*)$ %{REQUEST_URI}/\.\./\.\./img/ [R=302,NC,L]
这仅在 /images
中没有其他目录时有效。我可以让它像这样从 root 开始工作
RewriteRule ^images/(.*)$ /subsite/alpha/img/ [R=302,NC,L]
但我必须手动将其从 alpha
更新为 beta
、preprod
等
基本上,我需要一种方法来隔离 ^
和 images/
之间的所有内容。我尝试了一些变体:
RewriteRule ^(.*)images/(.*)$ //img/ [R=302,NC,L]
RewriteRule ^(.*)images/(.*)$ ^/img/ [R=302,NC,L]
但它不起作用,因为 .htaccess
在 alpha
中并且不知道它和 root 之间的内容。因此在上面, 不是
/subsite/alpha
而是 /alpha
和 images/
.
您可以使用 RewriteBase
并使用相对路径:
RewriteEngine On
RewriteBase /subsite/alpha/
RewriteRule ^images/(.*)$ img/ [R=302,NC,L]
否则如果您想避免使用 RewriteBase
然后使用此规则生成动态 RewriteBase
:
RewriteEngine On
RewriteCond [=11=]#%{REQUEST_URI} ^([^#]*)#(.*)$
RewriteRule ^.*$ - [E=BASE:%2]
RewriteRule ^(.*?/)?images/(.*)$ %{ENV:BASE}img/ [R=302,NC,L,NE]
动态 RewriteBase
的工作原理:
- 它将
REQUEST_URI
变量(完整路径)与RewriteRule
匹配的URI(相对于当前路径)进行比较,并在%{ENV:BASE}
变量中得到差异。 - 您可以在
RewriteCond
中使用从RewriteRule
捕获的[=19=]
,因为mod_rewrite
实际上 向后处理规则集 。它从RewriteRule
中的模式开始,如果匹配,则继续检查一个或多个RewriteCond
. - 因此,正如您在
RewriteCond
中看到的那样,LHS(测试字符串)可以使用反向引用变量,例如</code>、<code>
或%1
、%2
等,但 RHS 端即条件字符串 不能使用 这些</code>、<code>
或%1
、%2
个变量。 - 在 RHS 条件部分中,我们可以使用的唯一反向引用是 内部反向引用,即我们在此条件本身中捕获的组。它们被表示为
</code>、<code>
等 - 在您的
RewriteCond
中,第一个捕获的组是([^#]*)
。它将由内部反向引用 `\1. 表示
- 正如您所指出的,这条规则基本上是通过比较
%{REQUEST_URI}
和[=19=]
动态地找到RewriteBase
。%{REQUEST_URI}
的示例将是/directory/foobar.php
,对于同一示例 URI,[=19=]
的示例将是foobar.php
。^([^#]*)#(.*)$
将差异放在第二个捕获组%2
或</code> 中。这里 t 将使用值 <code>/directory/
填充%2
或</code>,稍后在设置环境变量 <code>%{ENV:BASE}
时使用,即E=BASE:%2
.