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]