我正在为一个用户建立一个网站,很明显,他们有很多子域,这些子域以前是定向到特定文件夹的。我宁愿找到某种方式来通过创建相关目录来自己进行管理,而不是每次他们要添加/更改它们时都不断添加虚拟主机或更改.htaccess
规则。
因此,我想到了使用包罗万象的虚拟主机,并使用.htaccess
将子域定向到正确文件夹的想法。
现在我知道有人问过类似的问题,但是我试图通过一个规则集来实现这一点,并且不执行完整的HTTP重定向。
目前我有以下规则,但遇到一个奇怪的问题
RewriteCond %{REQUEST_URI} !^/\.well-known
RewriteCond %{HTTP_HOST} !=www.example.co.uk [NC]
RewriteCond %{HTTP_HOST} ^(.+)\.example\.co\.uk [NC]
RewriteRule ^(.*)$ /%1/$1 [L,END,QSA]
基本上,这个想法是避免使用.well-known
,以便LetsEncrypt可以使用文档根目录获取任何子域的证书,避免使用应该使用标准路径的www.
,然后匹配并重定向其他任何路径子域。
如果没有END
,此操作将以服务器错误和日志中的exceeded the limit of 10 internal redirects
消息结尾。至少这似乎证实了它的匹配和重定向。
但是,据我所知,在使用END
关键字时,重写应该只发生一次;我看到了奇怪的行为。
对于特定路径,它似乎可以正常工作
GET /index.html HTTP/1.1
Host: journey.example.co.uk
HTTP/1.1 200 OK
... snip content from /journey/index.html ...
但是,如果我不提供路径,则似乎正在处理两次重定向。
GET / HTTP/1.1
Host: journey.example.co.uk
HTTP/1.1 404 Not Found
... snip ...
<p>The requested URL /journey/journey/index.html was not found on this server
... snip ...
鉴于使用%1
(应该是主机名的第一部分)$1
(在这种情况下应该只是/
或为空),我不是在重新编写的路径中查看两次如何以journey
结尾。
答案 0 :(得分:2)
想想我可能第十次翻阅了重写标志文档并找到了它,从而设法自己解决了这个问题。
nosubreq|NS Causes a rule to be skipped if the current request is an internal sub-request.
进一步的文档讨论了与我的问题无关的SSI,但确实提到了以下内容:
Also, when mod_dir tries to find out information about possible directory default files (such as index.html files), this is an internal subrequest, and you often want to avoid rewrites on such subrequests
我的理解是,对/
的请求导致mod_dir
对index.html
提出子请求,这导致两个请求和两次重写。
至少在一些快速测试中,将上述标志添加到规则中似乎可行。因此,以下规则似乎允许将任何子域重定向到文档根目录下的同名目录。
RewriteCond %{REQUEST_URI} !^/\.well-known
RewriteCond %{HTTP_HOST} !=www.example.co.uk [NC]
RewriteCond %{HTTP_HOST} ^(.+)\.example\.co\.uk [NC]
RewriteRule ^(.*)$ /%1/$1 [END,NS]