htaccess 请求重写为隐藏子目录,当省略尾部斜杠时会公开子目录

问题描述 投票:0回答:1

有一个域

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
    ,没有任何重定向按原样显示 URL。

  2. https://example.com/test
    (末尾没有斜杠)-> 可以重定向到
    https://example.com/example.com/test/
    ,但它会更改 URL 并添加不必要的目录路径,为什么?

如何使其在两种情况下都像#1 那样工作?

apache .htaccess mod-rewrite mod-dir
1个回答
1
投票

“问题”是 mod_dir 在内部重写发生后将尾部斜杠附加到 文件系统目录(使用 301 重定向)(只有这样 Apache 才知道它映射到目录)。为了能够从该目录(也由 mod_dir 处理)提供

DirectoryIndex
(即
index.html
),这是必要的。

要解决此问题,您需要在内部重写之前手动附加尾部斜杠(如果请求最终映射到目录),以便规范化 URL。不用说,包含尾部斜杠的 URL 是规范的,这是您应该在内部链接到的 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 重定向已被浏览器缓存。


旁白:

有一个域

example.com

,它是主域的别名。

假设您位于共享托管平台上,并且根据您拥有的托管类型,您通常可以将辅助域设置为“附加”域(而不是“别名”),这可以有效地允许您指向辅助域名直接位于子目录(有自己的

DocumentRoot

) - 因此无需在 
.htaccess
 中手动重写 URL。

© www.soinside.com 2019 - 2024. All rights reserved.