.htaccess - 递归地将斜杠映射到下划线(内部重定向)
Posted
技术标签:
【中文标题】.htaccess - 递归地将斜杠映射到下划线(内部重定向)【英文标题】:.htaccess - Recursively mapping slashes to underscores (internal redirect) 【发布时间】:2021-07-27 12:22:37 【问题描述】:与上一个问题相关:.htaccess - Recursively mapping slashes to underscores
被列为“完整解决方案”的代码工作了 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 ^([^.]+?)/?$ $1.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 ^([^/]+)/([^/]+/.+)$ $1_$2 [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 ^([^/]+)/([^/]+)$ /$1_$2 [L]
</IfModule>
可能的问题
如前所述,RewriteRule ^([^/]+)/([^/]+/.+)$ $1_$2 [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 上运行。有问题的代码大约 5 个月前从 CentOS 7 迁移而来,直到最近 7 天它一直运行良好。
就 Apache 设置和 .htaccess 文件而言,过去两周内没有任何变化。
【问题讨论】:
您能否在 Apache conf 中使用此指令启用跟踪级别RewriteLog
:LogLevel info rewrite:trace4
我愿意,但似乎我不需要 - 下面的两个答案都能实现我的目标。谢谢!
【参考方案1】:
这样吧:
<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 ^([^/]+)/(.+)$ $1_$2 [N,DPI]
# map the .php extension
RewriteCond %DOCUMENT_ROOT/$1.php -f
RewriteRule ^([^.]+?)/?$ $1.php [L]
</IfModule>
【讨论】:
我喜欢在继续之前过滤掉真实文件/文件夹的想法。我没有想到这一点——直到现在,我一直在按块过滤它们。你的要优雅得多。 哦。您是否认为“加倍”位是必需的,因为它正在搜索 / 之后的任何内容?我已经注释掉了,看起来还不错。当然,从逻辑上讲,它不是必需的。 如果过滤掉了真正的文件/文件夹规则,那么在每个规则之前不需要进一步检查。 我在谈论RewriteRule ^([^/]+)/([^/]+)$ $1_$2 [L]
- 这就是注释掉的内容。是的,早点-d
和-f
是个好主意。
是的,该规则可以被注释掉【参考方案2】:
试试:
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 ^([^.]+?)/?$ $1.php [L]
RewriteCond %REQUEST_FILENAME !-f
RewriteCond %REQUEST_FILENAME !-d
RewriteCond %REQUEST_URI ^(.+)\/(.*)$
RewriteRule ^ %1_%2 [L]
</IfModule>
【讨论】:
这也有效。如果有两个答案,我不确定什么适合我。由于上一个问题(发布答案,一年后)的帮助,我已将绿色对勾授予 @anubhava。 @Mark,你可以投票给我。并接受阿努巴瓦的。由你决定。以上是关于.htaccess - 递归地将斜杠映射到下划线(内部重定向)的主要内容,如果未能解决你的问题,请参考以下文章
使用 .htaccess 重定向 404 而不重定向尾部斜杠