这是我的目标:
/any-directory-or-subdirectory
应显示内容/any-directory-or-subdirectory/index.html
/any-directory-or-subdirectory/
应重定向至/any-directory-or-subdirectory
(无尾部斜杠)/any-directory-or-subdirectory/index.html
应该重定向到/any-directory-or-subdirectory
/any-directory-or-subdirectory/something.htm
我应该展示它自己的内容。
我已经在特定目录上完美地工作了:
DirectorySlash Off
RewriteEngine on
RewriteRule ^specific-dir$ /specific-dir/index.html [L,E=LOOP:1]
RewriteCond %{ENV:REDIRECT_LOOP} !1
RewriteRule ^specific-dir/$ /specific-dir [R=301,L]
RewriteCond %{ENV:REDIRECT_LOOP} !1
RewriteRule ^specific-dir/index.html$ /specific-dir [R=301,L]
我需要它在所有子目录(而不是特定子目录)上工作,并且让相同的功能在站点的根目录下工作。我尝试了很多方法来调整此代码,使其像这样工作,但到目前为止还没有成功。
答案1
您无需明确设置环境变量(例如LOOP
)即可避免重定向循环。您可以使用 Apache 自己的变量REDIRECT_STATUS
来实现此目的。REDIRECT_STATUS
在第一次处理请求时未设置,200
在第一次成功重写后设置为(如 200 OK)。
我还会安排您的指令,以便外部重定向位于内部重写之前,因为这些总是需要先执行。
为了使此方法适用于任何目录,您可以为目录名称设置正则表达式模式(如果处理任何级别的子目录,则为完整的 URL 路径),并包含一个检查请求是否映射到目录的条件。例如,尝试以下内容:
DirectorySlash Off
RewriteEngine on
# Strip trailing slash on directory
# (The root always has a slash, but the browser doesn't show it)
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule (.+)/$ /$1 [R,L]
# Strip trailing "/index.html" (including root)
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.*?)/?index\.html$ /$1 [R,L]
# Rewrite directory request to directory index
# (Any directory will already have had the trailing slash and "index.html" removed)
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule (.*) /$1/index.html [L]
(.*?)/?index\.html$
- 通过使捕获组非贪婪(即(.*?)
),它将不会捕获选修的斜杠。如果是,则可能会将尾部斜杠复制到代换并导致额外的重定向(因为第一条规则稍后会将其删除)。并且通过使所有内容都位于index.html
可选之前,它也将适用于文档根目录。
仅当您确定它正常工作时,才将临时(302)重定向更改为永久(301)。默认情况下,浏览器会严格缓存 301,因此可能会使测试出现问题。