我在Chris的回答中提到您可以在server_name中使用通配符和正则表达式,并且这些将会传递给您的rails实例。
server_name *; # handle requests from all domains
有四种方法可以在你的Rails应用程序中使用它(我知道这一点)。
“内容的大包”方法
什么都不做
如果你让Nginx的把所有的域相同的Rails应用程序,他们都得到了相同的内容。在这种情况下,www.abc.com和www.xyz.com可以访问相同的数据。这是最容易做到的,因为你什么都不做。
此解决方案的局限性在于您希望让域具有不同的内容。例如,如果www.abc.com/about和www.xyz.com/about应该是不同的页面,那么它就会变得棘手。
的“幕后的那个人”方法
使用的Nginx的“改写”
在某些情况下,你可以让Nginx的重写域名成子域,并传递到您的Rails应用程序。例如:
server_name *; # handle requests from all domains
rewrite ^(?:www.)?([^.]*)\..*$ $1.yourdomain.com last;
该正则表达式需要一点解释。它只是说从任何这些获得xyz:www.xyz.com,xyz.com,xzy.co.uk,www.xyz.co.uk.重写将这些请求中的任何一个更改为xyz.yourdomain.com。
这样做的好处是Nginx很快就做到了这一点,rails应用程序直到以后才会涉及,并且请求的内容可以限制在子域。例如,Page.where(subdomain: request.subdomain, permalink: params[:permalink])
。
虽然这是相当严格的,因为它意味着子域名和域名必须相同。也许这对你的应用程序来说是一个问题,可能不是。但是,尽管我在此子域中使用了$1
,但您可以轻松地将其作为url中的参数插入。例如,yourdomain.com/$1
会将来自www.xyz.com的请求重写到yourdomain.com/xyz。
此问题的另一个问题是“幕后男子”。虽然用户访问www.xyz.com重写意味着他们会在地址栏中看到xyz.yourdomain.com。
的“Rails的路”法
在ApplicationController中
使用Rails的请求对象,你可以使用你的应用程序控制器范围使用Rails的request
对象域名相关的内容。
在本例中,我们将使用ApplicationController来查找与域名关联的用户帐户。假设你有一个用户模型与domain_name
属性:
def domain_user
@domain_user ||= User.where(domain_name: request.domain()).take
end
Redis的可用于如果附加命中你的数据库中创建一个性能障碍缓存这些查找。到目前为止,我的应用还没有达到这一点。
这个解决方案的弱点是,虽然查找可能会发现www.xyz.com,它会错过xyz.com。为了适应这种情况,我们可以使用一些正则表达式:
def domain_user
request.domain.match /(?:www.)?(.*)/
@domain_user ||= User.where(domain_name: $1).take
end
这个正则表达式去掉www。如果它存在。剩下的就成了域名(我们在$1
里为我们存储红宝石)。
与Nginx重写解决方案不同,如果用户访问www.xyz.com,那么他们在地址栏中仍然可以看到。
使用路由约束
的“对我不起作用”法
另外,Rails的3及以上的有约束的,存在于产生路由表半动态的路由文件的功能。我说“半动态”,因为路由表是在应用程序启动时生成的。如果用户模型(在我们的示例中)发生变化,则需要特别注意重建路由表。对于分布在多个服务器上的应用程序,这可能难以管理,尽管people have done it。
到目前为止,我的所有应用程序最终(如果不是最初的话)都使用ApplicationController解决方案,因为它实际上是最干净和最容易实现的。从MCV的角度来看,这也很有意义。
+1设置多个别名并让你的Rails应用程序检测应执行哪一个检查主机变量。 – 2010-09-01 19:18:28
感谢您的评论。 – Chamnap 2010-09-02 10:49:52
我们完全按照克里斯描述的方式完成了Simone的建议,并且它工作正常。 – pjmorse 2010-10-18 11:55:10