使用 Apache mod_rewrite 进行 index.html 重定向,同时维护静态 index.html 文件

使用 Apache mod_rewrite 进行 index.html 重定向,同时维护静态 index.html 文件

这是我的目标:

  • /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,因此可能会使测试出现问题。

相关内容