.htaccess - 递归地将斜杠映射到下划线(内部重定向)
.htaccess - Recursively mapping slashes to underscores (internal redirect)
与之前的问题相关:
被列为“完整解决方案”的代码运行了 12 个月。然后停止工作。 .htaccess
代码也没有改变 - 只是为了让事情变得更难。
问题
谁能帮我实现期望的结果?
期望的结果
获取 https://domain.com/this/is/mah/page/structure 并显示位于网站根目录中的文件 /this_is_mah_page_strucutre.php。
当前代码
以下内容来自 htaccess 文件
<IfModule mod_negotiation.c>
Options -MultiViews
Options All -Indexes
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine on
DirectorySlash off
# Error Redirects
ErrorDocument 404 /incs/404.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php !-f
RewriteRule ^ - [R=404,L]
# remove .php
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
RewriteRule ^ /%1 [R=302,NE,L]
# map the .php extension
RewriteRule ^([^.]+?)/?$ .php [L]
# map the slashes to underscores
# when there are more than one / then "recursively" replace it by _
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# This next line appears to be the problem
RewriteRule ^([^/]+)/([^/]+/.+)$ _ [N,DPI]
# This next section appears to be doubling up, but was originally meant to catch anything that missed the previous block
# when there is only one / then replace it by _ and redirect
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)$ /_ [L]
</IfModule>
可能的问题
如前所述,RewriteRule ^([^/]+)/([^/]+/.+)$ _ [N,DPI]
似乎没有按预期工作。
如果 https://htaccess.madewithlove.be/?share=9bd3c5a0-4002-4324-a82e-0065b7286f82 可信,那么发生的事情是 [N] 没有导致递归 (a) 我需要,并且 (b) 它曾经提供。
MadeWithLove 测试结果表明 /this/is/mah/page/structure
正在变为 /this_is/mah/page/structure
。
我已经尝试重新调整 PCRE RegEx,@anubhava 也是如此 - 但一直无法使其正常工作。
服务器
服务器正在为 httpd 使用 2.4.37-30.module_el8.3.0+561+97fdbbcc
版本,在 CentOS 8 上是 运行。有问题的代码是从 CentOS 7 迁移大约 5 个月后,它一直在愉快地工作,直到大约最近 7 天。
就 Apache 设置和 .htaccess 文件而言,过去两周内没有任何变化。
尝试:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^(.+)\/(.*)$
RewriteRule ^ %1_%2 [L]
因此,您的完整 htaccess 是:
<IfModule mod_negotiation.c>
Options -MultiViews
Options All -Indexes
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine on
DirectorySlash off
# Error Redirects
ErrorDocument 404 /incs/404.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php !-f
RewriteRule ^ - [R=404,L]
# remove .php
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
RewriteRule ^ /%1 [R=302,NE,L]
# map the .php extension
RewriteRule ^([^.]+?)/?$ .php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^(.+)\/(.*)$
RewriteRule ^ %1_%2 [L]
</IfModule>
这样说:
<IfModule mod_negotiation.c>
Options All -Indexes -MukltiViews
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine on
DirectorySlash off
# Error Redirects
ErrorDocument 404 /incs/404.php
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
# remove .php
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
RewriteRule ^ /%1 [R=301,NE,L]
# map the slashes to underscores
# when there are more than one / then "recursively" replace it by _
# This next line appears to be the problem
RewriteRule ^([^/]+)/(.+)$ _ [N,DPI]
# map the .php extension
RewriteCond %{DOCUMENT_ROOT}/.php -f
RewriteRule ^([^.]+?)/?$ .php [L]
</IfModule>
与之前的问题相关:
被列为“完整解决方案”的代码运行了 12 个月。然后停止工作。 .htaccess
代码也没有改变 - 只是为了让事情变得更难。
问题
谁能帮我实现期望的结果?
期望的结果
获取 https://domain.com/this/is/mah/page/structure 并显示位于网站根目录中的文件 /this_is_mah_page_strucutre.php。
当前代码
以下内容来自 htaccess 文件
<IfModule mod_negotiation.c>
Options -MultiViews
Options All -Indexes
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine on
DirectorySlash off
# Error Redirects
ErrorDocument 404 /incs/404.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php !-f
RewriteRule ^ - [R=404,L]
# remove .php
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
RewriteRule ^ /%1 [R=302,NE,L]
# map the .php extension
RewriteRule ^([^.]+?)/?$ .php [L]
# map the slashes to underscores
# when there are more than one / then "recursively" replace it by _
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# This next line appears to be the problem
RewriteRule ^([^/]+)/([^/]+/.+)$ _ [N,DPI]
# This next section appears to be doubling up, but was originally meant to catch anything that missed the previous block
# when there is only one / then replace it by _ and redirect
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)$ /_ [L]
</IfModule>
可能的问题
如前所述,RewriteRule ^([^/]+)/([^/]+/.+)$ _ [N,DPI]
似乎没有按预期工作。
如果 https://htaccess.madewithlove.be/?share=9bd3c5a0-4002-4324-a82e-0065b7286f82 可信,那么发生的事情是 [N] 没有导致递归 (a) 我需要,并且 (b) 它曾经提供。
MadeWithLove 测试结果表明 /this/is/mah/page/structure
正在变为 /this_is/mah/page/structure
。
我已经尝试重新调整 PCRE RegEx,@anubhava 也是如此 - 但一直无法使其正常工作。
服务器
服务器正在为 httpd 使用 2.4.37-30.module_el8.3.0+561+97fdbbcc
版本,在 CentOS 8 上是 运行。有问题的代码是从 CentOS 7 迁移大约 5 个月后,它一直在愉快地工作,直到大约最近 7 天。
就 Apache 设置和 .htaccess 文件而言,过去两周内没有任何变化。
尝试:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^(.+)\/(.*)$
RewriteRule ^ %1_%2 [L]
因此,您的完整 htaccess 是:
<IfModule mod_negotiation.c>
Options -MultiViews
Options All -Indexes
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine on
DirectorySlash off
# Error Redirects
ErrorDocument 404 /incs/404.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php !-f
RewriteRule ^ - [R=404,L]
# remove .php
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
RewriteRule ^ /%1 [R=302,NE,L]
# map the .php extension
RewriteRule ^([^.]+?)/?$ .php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^(.+)\/(.*)$
RewriteRule ^ %1_%2 [L]
</IfModule>
这样说:
<IfModule mod_negotiation.c>
Options All -Indexes -MukltiViews
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine on
DirectorySlash off
# Error Redirects
ErrorDocument 404 /incs/404.php
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
# remove .php
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
RewriteRule ^ /%1 [R=301,NE,L]
# map the slashes to underscores
# when there are more than one / then "recursively" replace it by _
# This next line appears to be the problem
RewriteRule ^([^/]+)/(.+)$ _ [N,DPI]
# map the .php extension
RewriteCond %{DOCUMENT_ROOT}/.php -f
RewriteRule ^([^.]+?)/?$ .php [L]
</IfModule>