通过改进@amit-verma (https://stackoverflow.com/a/34726322/2837434) 的答案,为这个问题做出我自己的贡献:
在我的情况下,我遇到了一个问题,即RewriteCond %{REQUEST_FILENAME}.html -f 正在触发(相信文件存在),即使我没想到它:
%{REQUEST_FILENAME}.html 在所有这些情况下都给了我/var/www/example.com/page.html:
-
www.example.com/page(预计)
-
www.example.com/page/(也很期待)
-
www.example.com/page/subpage(不是预期的)
所以它试图加载的文件(相信如果是/var/www/example.com/page.html)是:
-
www.example.com/page => /var/www/example/page.html(好的)
-
www.example.com/page/ => /var/www/example/page/.html(不好)
-
www.example.com/page/subpage => /var/www/example/page/subpage.html(不好)
只有第一个实际上指向一个现有文件,其他请求给了我 500 个错误,因为它一直认为该文件存在并重复附加 .html。
我的解决方案是将RewriteCond %{REQUEST_FILENAME}.html -f替换为RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.html -f
这是我的整个.htaccess(我还添加了一条规则,将用户从/index 重定向到/):
# Redirect "/page.html" to "/page" (only if "/pages.html" exists)
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{THE_REQUEST} /(.+)\.html [NC]
RewriteRule ^(.+)\.html$ /$1 [NC,R=301,L]
# redirect "/index" to "/"
RewriteRule ^index$ / [NC,R=301,L]
# Load "/page.html" when requesting "/page" (only if "/pages.html" exists)
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.html -f
RewriteRule ^ /%{REQUEST_URI}.html [QSA,L]
这是一个结果示例,可帮助您理解所有案例:
考虑到我的服务器上只有 2 个 html 文件(index.html 和 page.html)
-
www.example.com/index.html => 重定向到 www.example.com
-
www.example.com/index => 重定向到 www.example.com
-
www.example.com => 渲染 /var/www/example.com/index.html
-
www.example.com/page.html => 重定向到www.example.com/page
-
www.example.com/page => 渲染/var/www/example.com/page.html
-
www.example.com/page/subpage => 返回 404 未找到
-
www.example.com/index.html/ => 返回 404 未找到
-
www.example.com/page.html/ => 返回 404 未找到
-
www.example.com/test.html => 返回 404 未找到
不再有 500 个错误?
另外,为了帮助您调试重定向,请考虑在浏览器中禁用网络缓存(因为旧的 301 重定向我在缓存中,这可能会引起一些头痛 ?):