【问题标题】:Serve index.php if index.html is not present in directory without a trailing slash如果 index.html 不存在于没有斜杠的目录中,则提供 index.php
【发布时间】:2021-09-29 13:29:03
【问题描述】:

我有一个带有子目录的 HTML 网站。

我需要的是:

  1. 访问不带斜杠的子目录,即。 (example.com/blog) 不是 (example.com/blog/)
  2. 如果某个子目录下没有index.html,它应该寻找index.php。

/blog/ 页面是一个带有自己的.htaccess 的 WordPress 页面。

这是我当前的根.htaccess:

RewriteEngine on
ErrorDocument 404 /error/error404.html


DirectorySlash Off
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}/index.html -f
RewriteRule ^(.*)$ /$1/index.html [L]

Wordpress .htaccess/blog/.htaccess:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]
</IfModule>

(这是由 Wordpress 自动生成的)

目前,html文件可以在某些子目录下访问,但不能通过index.php访问。我该怎么办?

【问题讨论】:

  • “我应该怎么做?” - 停止尝试使用重写引擎,DirectoryIndex 的工作是什么......?
  • 而且不应该花太多的心思来弄清楚简单地复制现有的条件和规则,并将index.html 替换为index.php,很可能也可以正常工作。
  • 还是一样。子目录有 .htaccess,如果我访问时没有斜杠,它会返回错误 403。

标签: apache .htaccess mod-rewrite


【解决方案1】:

DirectoryIndex 文档列出了在请求目录时尝试提供的文件。你不需要 mod_rewrite 这个。

但是,要在设置DirectorySlash Off 时使用DirectoryIndex,您需要手动将尾部附加到目录并进行内部重写,否则即使该目录包含DirectoryIndex 文档,也会触发403。 (因此需要禁用 mod_autoindex 以防止意外泄露信息 - DirectoryIndex 文档的存在不足以防止在设置 DirectorySlash Off 时自动生成目录列表。)

例如:

# Disable directory listings (mod_autoindex)
Options -Indexes

ErrorDocument 404 /error/error404.html

# Look for index.html then index.php in the directory being requested
DirectoryIndex index.html index.php

# Prevent mod_dir appending the trailing slash
DirectorySlash Off

RewriteEngine On

# If request a directory without a trailing slash then rewrite to append it
# This allows DirectoryIndex to work as intended
# - exclude the document root
RewriteCond $1 !/$
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule (.+) $1/ [L]

确保清除浏览器缓存。 mod_dir 发出 301(永久)重定向以附加尾部斜杠。


更新#1:

/blog/ 页面是一个带有自己的.htaccess 的 WordPress 页面。

这样做的问题是,当在子目录中启用重写引擎时,它会完全覆盖父配置中的 mod_rewrite 指令,因此不会附加斜线并且不会触发目录索引(并且不会触发 mod_rewrite 指令由于缺少斜线而被处理)。 (这感觉有点鸡和蛋。)

我成功解决此问题的唯一方法是将 WordPress 指令移动到父配置中(进行必要的更改)并完全删除 /blog/.htaccess。

例如,在上述指令之后附加以下修改后的 WordPress 指令:

# WordPress in "/blog" subdirectory
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteRule ^blog/index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^blog/. /blog/index.php [L]

更新#2:

是否有带有斜杠的 URL 以重定向到不带斜杠的 URL?例如,如果我访问/about/,它应该重定向到/about?

是的,我们可以做到这一点。由于我们要从所有内容(包括目录)中删除尾部斜杠,因此这基本上是无条件的。唯一需要注意的是,删除尾部斜杠的规则必须仅适用于来自客户端的直接请求,而不是通过稍后的重写来重写请求,这会将尾部斜杠附加到目录,否则会导致重定向循环。

除此之外:您显然需要确保所有内部链接不包含尾部斜杠,否则,用户将体验到外部重定向(对 SEO 和您的服务器不利)。

我们可以通过检查REDIRECT_STATUS 环境变量来做到这一点,它在初始请求中是empty,并在第一次成功重写后设置为200(如200 OK 状态) (将尾部斜杠附加到目录)。

例如,以下内容应紧跟在RewriteEngine 指令之后,在现有重写之前:

# Redirect direct requests to remove trailing slash from all URLs
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.+)/$ /$1 [R=302,L]

首先使用 302(临时)重定向进行测试,并在确认其按预期工作后更改为 301(永久)重定向。这是为了避免潜在的缓存问题。

总结

所有指令都已到位:

# Disable directory listings (mod_autoindex)
Options -Indexes

ErrorDocument 404 /error/error404.html

# Look for index.html then index.php in the directory being requested
DirectoryIndex index.html index.php

# Prevent mod_dir appending the trailing slash
DirectorySlash Off

RewriteEngine On

# Redirect direct requests to remove trailing slash from all URLs
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.+)/$ /$1 [R=301,L]

# If request a directory without a trailing slash then rewrite to append it
# - This allows DirectoryIndex to work as intended
# - Exclude the document root
RewriteCond $1 !/$
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule (.+) $1/ [L]

# WordPress in "/blog" subdirectory
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteRule ^blog/index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^blog/. /blog/index.php [L]

【讨论】:

  • 现在我很清楚了。但是在尝试了您的代码后,我从主页收到了内部服务器错误。主页有 index.html。子目录/页面有 index.html 或 index.php
  • @NicoReal 我已修改最后一个规则块以排除文档根目录,这可能是导致重写循环(内部服务器错误)的原因。
  • @MrWhite 到目前为止看起来不错。但问题是我无法在没有斜杠 (/blog) 的子目录下访问我的 Wordpress 安装。我可以使用尾部斜杠 (/blog/) 访问它。顺便提一下,这个 Wordpress 目录有一个单独的 .htaccess 文件
  • @MrWhite 你就是那个男人!非常感谢您的帮助!如果我需要使用带有斜杠的 URL 来重定向到不带斜杠的 URL,是否可以轻松编辑?例如,如果我访问“/about/”,它应该重定向到“/about”?
  • @NicoReal 我已经更新了我的答案 (update#2) 以包含重定向以删除尾部斜杠。
猜你喜欢
  • 1970-01-01
  • 2015-09-20
  • 2012-10-13
  • 2012-02-03
  • 1970-01-01
  • 1970-01-01
  • 2013-09-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多