将子域重定向到文件夹时,如何避免带有斜杠的URL的文件夹子域重复



Apache 2.4上的内部mod_rewrte重定向出现了一个奇怪的问题。

在我的.htaccess文件中,我使用以下指令将子域sub重定向到文件夹/sub

RewriteCond %{HTTP_HOST} ^sub.mydomain.com$ [NC]
RewriteRule ^((?!sub).*)$ /sub/$1  [NC]

Thos非常适用于https://sub.mydomain.com/articles/——URL在浏览器的地址字段中保持这样,并且不出所料,来自/sub/articles/index.html位置的数据将被提供/

但是,当我在浏览器中键入https://sub.mydomain.com/articles(注意缺少斜线(时,浏览器中的URL将更改为https://sub.mydomain.com/sub/articles/(注意重复的sub作为文件夹子域!(。

我想这是由Apache的默认行为引起的,即在无斜杠目录请求中添加斜杠作为外部重定向。斜杠的添加对我来说是可以的,但当然我想避免文件夹子域的重复。-我该怎么做?

是的,这是由于mod_dir在重写发生后向目录添加了一个斜杠(带有301重定向(,从而暴露了内部重写的URL/目录。

因此,规范URL需要是/articles/(带有尾部斜杠(,而不是/articles。我们可以在重写发生之前通过外部重定向来纠正这一问题。

(这避免了您必须禁用DirectorySlash,这仍然会给您留下规范化/重复内容的问题。(

例如,在现有重写之前,测试请求的URL路径(缺少尾部斜杠(是否作为目录存在于/sub目录中,如果是这样的话,请附加一个斜杠。

# Redirect to append trailing slash if exists as a dir inside "/sub"
RewriteCond %{HTTP_HOST} ^sub.mydomain.com [NC]
RewriteCond %{DOCUMENT_ROOT}/sub/$1 -d
RewriteRule ^((?!sub/).*[^/])$ /$1/  [R=301,L]

作为额外的优化,您可以通过排除看起来有文件扩展名的URL来避免对静态资产(自然不会以斜杠结尾(执行不必要的文件系统检查(这相对昂贵(。(这假设您没有具有文件扩展名的物理目录,例如/sub/somedir.xyz(

在上述规则中添加以下内容作为第二个条件(文件系统检查之前(:

RewriteCond %{REQUEST_URI} !.w{2,4}$

旁白:

RewriteCond %{HTTP_HOST} ^sub.mydomain.com$ [NC]
RewriteRule ^((?!sub).*)$ /sub/$1  [NC]

您可能应该在此RewriteRule指令上使用L标志。(NC标志应该是不必要的。(

正则表达式^((?!sub).*)$排除了任何简单启动sub的URL路径,该路径将包括/subfoo/subbar等(这自然会阻止在/sub目录中访问这些目录(。任何有效的请求都会以/sub/开头(后面有一个斜杠(,因此应该包括在负前瞻中,就像我在上面的规则中所做的那样。

如果还没有,如果应该公开/发现该目录,还可以考虑重定向以从直接请求中删除/sub/