在anubhava's answer 和Jon 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$:
-
^(.*):: 匹配 misc/subdir/file.xyz::
-
\1 是第一个捕获组,misc/subdir/file.xyz
-
(.*?)\1$ 变为 (.*?)misc/subdir/file.xyz$
- 因此,我们的第二个捕获组
(.*?) 匹配剩余的/path_to/current_folder/
而我们的RewriteRule 将CWD 设置为%2,这是CondPattern 的第二个捕获组。