将通过中央控制器脚本提供服务的站点划分为两个依赖于上下文的子域



我有一个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

实际上,他们希望将网站划分为两个子域,由幕后的同一系统提供服务。

第一部分(用于/bookbooking(只需将其添加到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]

最新更新