x.com/example
重定向到
x.com/example/
自从
/example
是一个物理目录,mod_dir“修复”了URL,并在后面的斜杠中添加301(永久)重定向。尾部斜线为
必修的
以便服务器
DirectoryIndex
(即。
index.html
在这种情况下)。
但是,我们可以防止mod_dir在尾部斜杠后面附加
DirectorySlash Off
指令。但是,我们必须发布一个内部重写来附加尾部斜杠,否则
目录索引
文件将不会送达(如上所述)。(或者,我们可以直接重写到索引文档。)
设置时
DirectorySlash关闭
我们还必须确保禁用目录列表(modautoindex),因为该目录中存在索引文档将不再阻止目录列表。
为了解决潜在的规范化问题,您现在需要向另一个方向“重定向”,以删除请求的URL上的任何尾部斜杠。例如请求
/example/
现在需要重定向回
/示例
.
此外,以下规则重写到相应的
.html
文件不完全正确:
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^ %{REQUEST_URI}.html [NC,L]
这个
条件
(使用
REQUEST_FILENAME
)不一定要测试您最终要在中重写到的相同URL
替代
(使用
REQUEST_URI
).因此,在某些情况下(例如,当请求目录中不存在的文件时,该文件恰好也映射到
.html
文件),您可以得到一个重写循环(500内部服务器错误)。请参阅以下关于ServerFault的问题/答案,该问题/答案将对此进行详细介绍:
https://serverfault.com/questions/989333/using-apache-rewrite-rules-in-htaccess-to-remove-html-causing-a-500-error
这同样适用于早期的规则,该规则将
.php
扩大
综合以上几点,我们得出以下结论:
# [NEW] Directory listing (mod_autoindex) must be disabled
Options -Indexes
# [NEW] Prevent mod_dir appending the trailing slash
DirectorySlash Off
RewriteEngine On
# Disable http
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Disable www.
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
# Redirect /index.html in URL to /
RewriteRule (.*)index\.html$ /$1 [R=301,L]
# Redirect xxx.html in URL to just xxx
RewriteCond %{THE_REQUEST} /([^.?]+)\.html [NC]
RewriteRule ^ /%1 [R=301,L]
# [NEW] Redirect to remove trailing slash on direct requests
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.+)/$ /$1 [R=301,L]
# [NEW] Internal rewrite to append trailing slash to directories
RewriteCond %{DOCUMENT_ROOT}/$1 -d
RewriteRule (.+) $1/ [L]
# /random run random.php
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^\.]+)$ $1.php [L]
# Append ".html" if corresponding file exists
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.html -f
RewriteRule ^ %{REQUEST_URI}.html [L]
与您的即时问题相关的新规则用表示
[NEW]
.
在测试之前,您需要清除浏览器缓存,因为附加了尾部斜杠的301(永久)重定向将被缓存。使用302(临时)重定向进行测试,以避免潜在的缓存问题。
附加说明:
-
在测试同一个请求加上
.php
做
映射到文件,这些都是互斥的事件,特别是因为
RewriteRule
图案
排除点(所以排除具有文件扩展名的URL),所以我删除了
条件
.
-
无需在中反斜杠转义文字点
RewriteCond
测试字符串
因为这是一个“普通”字符串,而不是正则表达式。
-
不需要
NC
的两个上的旗帜
重写规则
指令,因为regex已经匹配a-z和a-z。
-
我对规范重定向进行了分组
之前
内部重写。
# Redirect xxx.html in URL to nach xxx
RewriteCond %{THE_REQUEST} /([^.]+)\.html [NC]
RewriteRule ^ /%1 [NC,L,R]
请注意,我还在中修改了regex
条件
以避免匹配潜在的查询字符串,否则为表单的请求
/foo.html?bar.html
将导致双重重定向,并且查询字符串将损坏。
注意:您目前没有相应的规则
.php
请求。(您可以在同一规则中处理这两个问题。)