Nginx将非www前缀域重写为www前缀域

我看到Nginx的HttpRewriteModule文档有一个例子,把一个www前缀的域重写为一个非www前缀的域:

if ($host ~* www\.(.*)) { set $host_without_www $1; rewrite ^(.*)$ http://$host_without_www$1 permanent; # $1 contains '/foo', not 'www.mydomain.com/foo' } 

我怎样才能做到相反 – 将一个非www前缀域重写到一个www前缀域? 我想也许我可以做下面的事情,但Nginx不喜欢嵌套的if语句。

 if ($host !~* ^www\.) { # check if host doesn't start with www. if ($host ~* ([a-z0-9]+\.[a-z0-9]+)) { # check host is of the form xxx.xxx (ie no subdomain) set $host_with_www www.$1; rewrite ^(.*)$ http://$host_with_www$1 permanent; } } 

此外,我想这个工作的任何域名没有明确告诉Nginx重写domain1.com – > www.domain1.com,domain2.com – > www.domain2.com等,因为我有大量的域重写。

正如在Nginx文档中提到的那样,在可能的情况下 , 应该避免在Nginx中使用if指令 ,因为if在configuration中有一个if ,服务器就需要评估每一个请求来决定是否匹配。

更好的解决scheme是多个服务器指令。

 server { listen 80; server_name website.com; return 301 $scheme://www.website.com$request_uri; } server { listen 80; server_name www.website.com; ... } 

如果您尝试提供启用了SSL(HTTPS)的网站,则您或多或less地拥有三种不同的选项。

  1. 设置多个IP地址,每个服务器伪指令监听自己的IP(或者不同的端口,如果这是您的select)。 这个选项需要website.comhttp://www.website.com的; SSL证书,所以要么有通配符证书,要么有UNI证书(多个域名),要么只有两个不同的证书。
  2. 在应用程序中重写。
  3. 使用dreaded if指令。

还有一个select使用SNI,但我不确定这是完全支持截至目前 。

 if ($host !~* ^www\.) { rewrite ^(.*)$ http://www.$host$1 permanent; } 

那么我猜我不需要外部的“if”语句,因为我只是检查forms为xxx.xxx的域。 以下对我来说,虽然它不健壮。 让我知道是否有更好的解决scheme。

  if ($host ~* ^([a-z0-9\-]+\.(com|net|org))$) { set $host_with_www www.$1; rewrite ^(.*)$ http://$host_with_www$1 permanent; } 

编辑:添加连字符正则expression式,因为它是一个主机名中的有效字符。

 if ($host ~* ^[^.]+\.[^.]+$) { rewrite ^(.*)$ http://www.$host$1 permanent; } 

只有获得有效的主机名是可能的,因为请求将永远不会到达你的服务器,所以不需要build立你自己的validation逻辑。

nginx文档警告不要使用if来重写。 请看这里的链接: http : //wiki.nginx.org/Pitfalls#Server_Name