在.htaccess中重写引擎以捕获不以html结尾的文件
-
03-07-2019 - |
题
我想在标准的LAMP托管情况下使用mod重写将 / directory 等网页地址转换为 /directory/index.html 。我对以斜线结尾的地址有效。我找不到办法处理不以斜线结尾的地址。
它应该起作用的是:
rewriterule ^(.*)/$ $1/index.html [L] /* addresses ending in / */
rewriterule ^(.*(?!html))$ $1/index.html [L] /* where the problem is */
但第二行会导致500服务器错误。如果我在第二行添加一个字母x:
rewriterule ^(.*)/$ $1/index.html [L]
rewriterule ^(.*x(?!html))$ $1/index.html [L]
它开始工作,但仅适用于以x 结尾的目录名称。我尝试用许多不同的东西替换x。任何比真实字符更复杂的东西(如[^ x]或。+)都会产生500服务器错误。
而且,为了满足自己的好奇心,有没有人知道为什么添加一个真实的字母会使服务器错误与功能完善的规则产生差异?
[接受的答案] 感谢Gumbo,我能够使用重写来近似解决方案:
rewritecond %{REQUEST_URI} !\.[^/]+$ rewriterule (.+) $1/index.html [L]
这样可行,但过滤器不仅仅是.html - 它可以阻止其他页面。不幸的是,
rewritecond %{REQUEST_URI} !\.html$
导致服务器错误:
由于可能的配置错误,请求超出了10个内部重定向的限制。如有必要,使用'LimitInternalRecursion'来增加限制。
我仍然想知道原因:
rewriterule ^(.*(?!html))$ $1/index.html [L]
导致循环。上半部分应该检查是否以.html结尾。由于下半部分添加 .html,它看起来像功能相当于:
while(substr($address,-4)!='html') $address.='html'
显然我错过了什么。
解决方案
使用 RewriteCond
指令检查URL路径是否以 .html
结尾:
RewriteCond %{REQUEST_URI} !\.html$
RewriteRule ^(.*[^/])?/?$ $1/index.html [L]
修改   您正在使用预见断言((?!…)
)。但是。*
之后没有任何东西(只有 $
)。因此,请尝试使用后视断言:
RewriteRule ^.*$(?<!html) <*>/index.html [L]
但请注意,您可能需要使用Apache 2.2来使用这些断言。
其他提示
嗯,为了让它真正发挥作用,你可以使用负面的后视而不是前瞻:
RewriteRule ^(.*)(?<!html)$ $1/index.html [L]
我不确定为什么添加'x'会使其正常工作,如果我弄明白的话,我会编辑。
为什么添加 x
使其工作:
如果替换将匹配正则表达式,则将再次应用RewriteRule。例如,这会导致错误:
RewriteRule ^(.*)$ $1.rb
因为它会将 script
替换为 script.rb
。这与正则表达式匹配,因此它一次又一次地用 script.rb.rb
替换 script.rb
......
错误日志中暗示了这一点:
Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary.
在您的示例中,您将index.html添加到最后。当正则表达式末尾有 x
时,它将与您的替换匹配,后者以 l
结尾。