我脑子坏掉了
有一个域“example.com”,它是主域的别名。 我的目标是将“example.com”指向主站点的子目录“example.com/”。 该子目录有一个子目录“test/”。
.htaccess 是
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com$ [NC]
RewriteRule ^(.*)?$ example.com/$1 [L,NC]
#1 https://example.com/test/ -> 这效果很好,它显示“./example.com/test/index.html”,没有任何重定向显示原样的网址。
#2 https://example.com/test(末尾没有斜杠)-> 用作重定向到“https://example.com/example.com/test/”,它更改 url 并添加不必要的目录路径,为什么?
如何使其在两种情况下都像#1 那样工作?
“问题”是 mod_dir 在内部重写发生后将尾部斜杠附加到 文件系统目录(使用 301 重定向)(只有这样 Apache 才知道它映射到目录)。为了能够从该目录提供
DirectoryIndex
(即 index.html
),这是必要的。
要解决此问题,您需要在内部重写之前手动附加尾部斜杠(如果请求最终映射到目录),以便规范化 URL。
例如:
# Append trailing slash if the file-path that the URL maps to is a directory
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com [NC]
RewriteCond %{DOCUMENT_ROOT}/example.com/$1 -d
RewriteRule (.+[^/])$ /example.com/$1/ [R=301,L]
# Rewrite Requests to subdirectory
RewriteCond %{HTTP_HOST} ^(www\.)?example\.com [NC]
RewriteRule (.*) example.com/$1 [L]
注意:正则表达式 ^(.*)?$
与简单的
(.*)
相同,并且该规则不需要
NC
标志,因为正则表达式本质上不区分大小写。
旁白: 事实上,您现有的重写规则完全有效(并且不会导致重写循环)取决于 .htaccess
子目录中存在的另一个
/example.com
文件,该文件也包含 mod_rewrite 指令。我在上面的规则中也使用了这个假设。否则,您将需要额外的检查以避免重写循环(以及不必要的文件系统检查)。首先使用 302(临时)重定向进行测试,以避免潜在的缓存问题。您需要确保清除所有(浏览器)缓存,因为早期(错误的)301 重定向已被浏览器缓存。