我有一个Apache服务器,它将对所有不存在的资源的请求传递给index.php
充当中央控制器。对此的 htaccess 规则是:
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ /index.php [NC,L]
在此服务器上,我有两个子域指向同一个webroot目录:
www.example.com
和
booking.example.com
我的客户希望预订部分(/book
(使用booking
子域提供服务,而网站的其余部分应该保留在www
上。
所以他们想要诸如
https://www.example.com/about-us
和
https://booking.example.com/book
这意味着对https://booking.example.com/about-us
的请求需要重定向到https://www.example.com/about-us
,并且按照相同的思路,对https://www.example.com/book
的请求需要重定向到https://booking.example.com/book
。
实际上,他们希望将网站划分为两个子域,由幕后的同一系统提供服务。
第一部分(用于/book
booking
(只需将其添加到htaccess即可轻松实现:
# redirect all requests on www. made to /book to booking subdomain
RewriteCond %{HTTP_HOST} ^www.
RewriteRule ^book(.*)$ https://booking.example.com/book$1 [L,R=301]
对应项(向www
发送非/book
请求(也很容易:
# redirect all requests on booking. made to not /book to www subdomain
RewriteCond %{HTTP_HOST} ^booking.
RewriteCond %{REQUEST_URI} !^/book
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
在模拟中,这完全符合预期:
https://htaccess.madewithlove.be?share=990cff3e-7739-5bff-912f-493ae76e3a4c
https://htaccess.madewithlove.be?share=a005713e-97bf-59af-b89a-f2c5ceae13ed
问题是index.php
重定向搞砸了,我不完全明白如何。
如果我只有两个规则中的一个处于活动状态,它们分别工作正常。
但是,如果我同时激活两者并转到https://www.example.com
并点击链接https://www.example.com/book
我最终会得到https://www.example.com/index.php
而不是预期的https://booking.example.com/book
。
据我所知,这是因为在重定向到booking
子域后,第二条规则的REQUEST_URI
检查,该规则在booking
上查找请求,而不是/book
,似乎具有REQUEST_URI
的值,因为index.php
。
我不明白的是为什么第二次检查会查看具有该值REQUEST_URI
- 我本来会假设第一条规则中的[L,R=301]
会触发对被评估为这样的服务器的新请求,但事实似乎并非如此。
相反,index.php
请求的内部解析似乎传递给了第二条规则。
我该如何解决此问题?
编辑:为了清楚起见 - htaccess的rewrite
部分如下所示:
# redirect all requests on www. made to /book to booking subdomain
RewriteCond %{HTTP_HOST} ^www.
RewriteRule ^book(.*)$ https://booking.example.com/book$1 [L,R=301]
# redirect all requests on booking. made to not /book to www subdomain
RewriteCond %{HTTP_HOST} ^booking.
RewriteCond %{REQUEST_URI} !^/book
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ /index.php [NC,L]
尝试更改:
RewriteCond %{REQUEST_URI} !^/book
自
RewriteCond %{THE_REQUEST} !s/book
对,所以我通过为第二个重定向添加一个RewriteRule
来解决这个问题 -booking
为不/book
请求www
- 不触发/index.php
.
另请注意,我添加了一个规则,允许在booking
子域上加载资源(js,css(。
# redirect all requests on www. made to /book to booking subdomain
RewriteCond %{HTTP_HOST} ^www.
RewriteRule ^book(.*)$ https://booking.example.com/book$1 [L,R=301]
# redirect all requests on booking. made to not /book to www subdomain
RewriteCond %{HTTP_HOST} ^booking.
RewriteCond %{REQUEST_URI} !^/book
RewriteCond %{REQUEST_URI} !^/index.php #don't fire on index.php
RewriteCond %{REQUEST_URI} !(.js|.css) #allow js / css
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ /index.php [NC,L]