Nginx没有www到www和www到no-www

The*_*Kid 481 ubuntu redirect nginx rackspace no-www

在Rackspace云上使用nginx跟随一个教程并搜索网络,到目前为止无法对此进行排序.

我希望www.mysite.com在.htaccess中正常访问mysite.com以获取SEO和其他原因.

我的/etc/nginx/sites-available/www.example.com.vhost配置:

server {
       listen 80;
       server_name www.example.com example.com;
       root /var/www/www.example.com/web;

       if ($http_host != "www.example.com") {
                 rewrite ^ http://example.com$request_uri permanent;
       }
Run Code Online (Sandbox Code Playgroud)

我也试过了

server {
       listen 80;
       server_name example.com;
       root /var/www/www.example.com/web;

       if ($http_host != "www.example.com") {
                 rewrite ^ http://example.com$request_uri permanent;
       }
Run Code Online (Sandbox Code Playgroud)

我也试过了.第二次尝试都会给出重定向循环错误.

if ($host = 'www.example.com' ) {
rewrite ^ http://example.com$uri permanent;
}
Run Code Online (Sandbox Code Playgroud)

我的DNS设置为标准:

site.com 192.192.6.8 A type at 300 seconds
www.site.com 192.192.6.8 A type at 300 seconds
Run Code Online (Sandbox Code Playgroud)

(示例IP和文件夹已用于示例,并在将来帮助人们).我使用的是Ubuntu 11.

The*_*Kid 785

HTTP解决方案

文档中,"正确的方法是为example.org定义一个单独的服务器":

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

server {
    listen       80;
    server_name  www.example.com;
    ...
}
Run Code Online (Sandbox Code Playgroud)

HTTPS解决方案

对于那些想要包括https://...... 的解决方案的人

server {
        listen 80;
        server_name www.domain.com;
        # $scheme will get the http protocol
        # and 301 is best practice for tablet, phone, desktop and seo
        return 301 $scheme://domain.com$request_uri;
}

server {
        listen 80;
        server_name domain.com;
        # here goes the rest of your config file
        # example 
        location / {

            rewrite ^/cp/login?$ /cp/login.php last;
            # etc etc...

        }
}
Run Code Online (Sandbox Code Playgroud)

注意:我最初没有包含https://在我的解决方案中,因为我们使用了均衡器,而且我们的https://服务器是一个高流量的SSL支付服务器:我们不混用https://和http://.


要检查nginx版本,请使用nginx -v.

使用nginx重定向从URL中剥离www

server {
    server_name  www.domain.com;
    rewrite ^(.*) http://domain.com$1 permanent;
}

server {
    server_name  domain.com;
    #The rest of your configuration goes here#
}
Run Code Online (Sandbox Code Playgroud)

所以你需要有两个服务器代码.

使用nginx重定向将www添加到网址

如果你需要的是相反的,要从domain.com重定向到www.domain.com,你可以使用:

server {
    server_name  domain.com;
    rewrite ^(.*) http://www.domain.com$1 permanent;
}

server {
    server_name  www.domain.com;
    #The rest of your configuration goes here#
}
Run Code Online (Sandbox Code Playgroud)

正如您可以想象的那样,这恰恰相反,并且与第一个示例的工作方式相同.这样,你就不会得到SEO标记,因为它是完整的烫发重定向和移动.没有WWW被强制显示目录!

我的一些代码如下所示,以获得更好的视图:

server {
    server_name  www.google.com;
    rewrite ^(.*) http://google.com$1 permanent;
}
server {
       listen 80;
       server_name google.com;
       index index.php index.html;
       ####
       # now pull the site from one directory #
       root /var/www/www.google.com/web;
       # done #
       location = /favicon.ico {
                log_not_found off;
                access_log off;
       }
}
Run Code Online (Sandbox Code Playgroud)

  • 您的重写应该成为返回,如`return 301 $ scheme://domain.com$request_uri;`.没有必要捕获任何模式,请参阅[Nginx陷阱](http://wiki.nginx.org/Pitfalls#Multiple_Index_Directives) (16认同)
  • @TheBlackBenzKid对不起,也许我错过了什么,但更新的解决方案无法正常工作.这是因为听80 - 你说,只有HTTP匹配这个.如果相同的配置用于HTTP和HTTPS,应该有更多的端口可以监听...或者?但是definitelly帮助了我,+1.谢谢你的答复.干杯. (4认同)
  • @puk欣赏它.Nginx是惊人的,但是与服务器版本以及操作系统和服务器硬件更改保持同步的良好文档非常令人厌烦.为我提供服务的最佳资源是howtoforge.com,因为它支持RackSpace云版本.上面的一些命令在以后的版本中不起作用.但这个nginx/0.8.54--相信我,最好的nginx服务器)无需升级或更新.工作良好.每天100,000次独特点击,平均每天4200次交易.Nginx是RAPID.比如使用没有流量的网站. (3认同)
  • @TheBlackBenzKid这只是注意.我找到了工作解决方案.在您的示例中,只应添加Listen 443并完成工作. (3认同)
  • answer is wrong. it redirects all subdomains to www. (2认同)

Fle*_*der 385

实际上你甚至不需要重写.

server {
    #listen 80 is default
    server_name www.example.com;
    return 301 $scheme://example.com$request_uri;
}

server {
    #listen 80 is default
    server_name example.com;
    ## here goes the rest of your conf...
}
Run Code Online (Sandbox Code Playgroud)

我的答案是越来越多的投票,但上面也是如此.你不应该rewrite在这种情况下使用a .为什么?因为nginx必须处理并开始搜索.如果你使用return(应该在任何nginx版本中都可用),它会直接停止执行.这在任何情况下都是优选的.

将非SSL和SSL重定向到非www对应方:

server {
    listen               80;
    listen               443 ssl;
    server_name          www.example.com;
    ssl_certificate      path/to/cert;
    ssl_certificate_key  path/to/key;

    return 301 $scheme://example.com$request_uri;
}

server {
    listen               80;
    listen               443 ssl;
    server_name          example.com;
    ssl_certificate      path/to/cert;
    ssl_certificate_key  path/to/key;

    # rest goes here...
}
Run Code Online (Sandbox Code Playgroud)

如果您的服务器仅侦听端口80(默认)并且listen选项不包含关键字,则该$scheme变量将仅包含.不使用变量不会获得任何性能.httpssl

请注意,如果使用HSTS,则需要更多服务器块,因为不应通过非加密连接发送HSTS标头.因此,您需要具有重定向的未加密服务器块和具有重定向和HSTS标头的加密服务器块.

将所有内容重定向到SSL(UNIX上的个人配置,IPv4,IPv6,SPDY,...):

#
# Redirect all www to non-www
#
server {
    server_name          www.example.com;
    ssl_certificate      ssl/example.com/crt;
    ssl_certificate_key  ssl/example.com/key;
    listen               *:80;
    listen               *:443 ssl spdy;
    listen               [::]:80 ipv6only=on;
    listen               [::]:443 ssl spdy ipv6only=on;

    return 301 https://example.com$request_uri;
}

#
# Redirect all non-encrypted to encrypted
#
server {
    server_name          example.com;
    listen               *:80;
    listen               [::]:80;

    return 301 https://example.com$request_uri;
}

#
# There we go!
#
server {
    server_name          example.com;
    ssl_certificate      ssl/example.com/crt;
    ssl_certificate_key  ssl/example.com/key;
    listen               *:443 ssl spdy;
    listen               [::]:443 ssl spdy;

    # rest goes here...
}
Run Code Online (Sandbox Code Playgroud)

我猜你现在可以想象其他具有这种模式的化合物了.

更多我的配置?去这里这里.

  • 谢谢你.Repped. (7认同)
  • 在第二个块"将两个,非SSL和SSL重定向到非www对应方:",两个服务器块都应该具有SSL指令,因为浏览器需要在重定向到示例之前验证www.example.com的证书.COM. (4认同)
  • 如果您使用的是HSTS,则您的Chrome无法访问您的http:// www域名.请尽可能详细地打开一个新问题,我会帮助您(您可以在此处发布问题的URL作为评论). (3认同)

Mar*_*ger 36

您可能会发现要为更多域使用相同的配置.

以下代码段在任何域名之前删除www:

if ($host ~* ^www\.(.*)$) {
    rewrite / $scheme://$1 permanent;
}
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢这种方式比专用服务器块更好.将`http`改为`$ scheme` (7认同)
  • 更好的是,不能相信很多人会将域硬编码到这个任务的配置中. (2认同)
  • 不幸的是,我没有找到没有“如果”的方法。我对许多域使用相同的配置,不能选择对域名进行硬编码。任何建议/评论表示赞赏! (2认同)

Red*_*Red 26

您需要两个服务器块.

将这些放入您的配置文件中,例如 /etc/nginx/sites-available/sitename

假设您决定将http://example.com作为要使用的主要地址.

您的配置文件应如下所示:

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

        # this is the main server block
        # insert ALL other config or settings in this server block
}
Run Code Online (Sandbox Code Playgroud)

第一个服务器块将保留指令以使用"www"前缀重定向任何请求.它使用"www"前缀监听URL请求并重定向.

它没有别的.

第二个服务器块将保留您的主要地址 - 您要使用的URL.所有其它的设置去这里一样root,index,location等检查的默认文件对这些设置,您可以包括在服务器块.

服务器需要两个DNS A记录.

Name: @ IPAddress: your-ip-address (for the example.com URL)

Name: www IPAddress: your-ip-address (for the www.example.com URL)
Run Code Online (Sandbox Code Playgroud)

对于ipv6,使用您的-ipv6-address创建一对AAAA记录.


Eri*_*son 23

以下是如何为多个www到无www服务器名称执行此操作(我将其用于子域):

server {
        server_name 
             "~^www\.(sub1.example.com)$"
             "~^www\.(sub2.example.com)$"
             "~^www\.(sub3.example.com)$";
         return 301 $scheme://$1$request_uri ;
}
Run Code Online (Sandbox Code Playgroud)


Vis*_*ioN 16

这个解决方案来自我个人的经验.我们使用了几个Amazon S3存储桶和一个服务器来重定向non-wwwwww域名以匹配S3"主机"标头策略.

我为nginx服务器使用了以下配置:

server {
    listen 80;
    server_name ~^(?!www\.)(?<domain>.+)$;
    return 301 $scheme://www.$domain$request_uri;
}
Run Code Online (Sandbox Code Playgroud)

这匹配指向服务器的所有域名,以及从www.重定向到的任何内容www.<domain>.以同样的方式,你可以从做相反重定向wwwnon-www.


Mat*_*sen 15

我结合了所有简单答案中最好的,没有硬编码域.

301永久重定向从非www到www(HTTP或HTTPS):

server {
    if ($host !~ ^www\.) {
        rewrite ^ $scheme://www.$host$request_uri permanent;
    }

    # Regular location configs...
}
Run Code Online (Sandbox Code Playgroud)

如果你喜欢非HTTPS,非www到HTTPS,www同时重定向:

server {
    listen 80;

    if ($host !~ ^www\.) {
        rewrite ^ https://www.$host$request_uri permanent;
    }

    rewrite ^ https://$host$request_uri permanent;
}
Run Code Online (Sandbox Code Playgroud)


cns*_*nst 13

  1. 最佳做法:server带硬编码的单独server_name

nginx的最佳实践是对server这样的重定向使用单独的名称(不与server主配置共享),对所有内容进行硬编码,并且完全不使用正则表达式。

如果您使用的是HTTPS,则可能还需要对域进行硬编码,因为您必须预先知道要提供的证书。

server {
    server_name www.example.com;
    return  301 $scheme://example.com$request_uri;
}
server {
    server_name www.example.org;
    return  301 $scheme://example.org$request_uri;
}
server {
    server_name example.com example.org;
    # real configuration goes here
}
Run Code Online (Sandbox Code Playgroud)
  1. 在内部使用正则表达式 server_name

如果您有许多站点,并且不希望获得最出色的性能,但是希望每个站点在www.前缀方面都具有相同的策略,则可以使用正则表达式。使用单独的最佳实践server仍然有效。

请注意,如果您使用https,则此解决方案会比较棘手,因为如果您希望此方法正常运行,则必须具有一个证书来覆盖所有域名。


wwwwwwW /在一个专用的单正则表达式server的所有网站:

server {
    server_name ~^(?!www\.)(?<domain>.+)$;
    return  301 $scheme://www.$domain$request_uri;
}
Run Code Online (Sandbox Code Playgroud)

www以非www瓦特/正则表达式在专用的单一server的所有网站:

server {
    server_name ~^www\.(?<domain>.+)$;
    return  301 $scheme://$domain$request_uri;
}
Run Code Online (Sandbox Code Playgroud)

wwwwww专用server于某些网站的非w /正则表达式:

这可能是必要的限制正则表达式覆盖只有一对夫妇域,那么你可以使用这样的事情只匹配www.example.orgwww.example.com并且www.subdomain.example.net

server {
    server_name ~^www\.(?<domain>(?:example\.org|example\.com|subdomain\.example\.net))$;
    return  301 $scheme://$domain$request_uri;
}
Run Code Online (Sandbox Code Playgroud)

使用nginx测试正则表达式

您可以测试正则表达式是否可以pcretest在您的系统上正常工作,这与pcre您的nginx用于正则表达式的库完全相同:

% pcretest 
PCRE version 8.35 2014-04-04

  re> #^www\.(?<domain>(?:example\.org|example\.com|subdomain\.example\.net))$#
data> test
No match
data> www.example.org
 0: www.example.org
 1: example.org
data> www.test.example.org
No match
data> www.example.com
 0: www.example.com
 1: example.com
data> www.subdomain.example.net
 0: www.subdomain.example.net
 1: subdomain.example.net
data> subdomain.example.net
No match
data> www.subdomain.example.net.
No match
data> 
Run Code Online (Sandbox Code Playgroud)

请注意,您不必担心尾随点或大小写,因为nginx已经处理了它,根据“主机”标头中包含尾随点的nginx服务器名称regex


  1. 散布if在现有server/ HTTPS中:

最终解决方案通常不被视为最佳实践,但是,它仍然可以正常工作。

实际上,如果您使用的是HTTPS,则最终的解决方案可能最终更易于维护,因为您不必在不同的server定义之间复制粘贴一堆ssl指令,而只需将代码段放入所需的服务器,从而使调试和维护站点变得更加容易。


wwwwww

if ($host ~ ^(?!www\.)(?<domain>.+)$) {
    return  301 $scheme://www.$domain$request_uri;
}
Run Code Online (Sandbox Code Playgroud)

www到非www

if ($host ~ ^www\.(?<domain>.+)$) {
    return  301 $scheme://$domain$request_uri;
}
Run Code Online (Sandbox Code Playgroud)

硬编码单个首选域

如果您希望获得更高的性能以及单个域server可以使用的多个域之间的一致性,那么显式地对单个首选域进行硬编码仍然有意义:

if ($host != "example.com") {
    return  301 $scheme://example.com$request_uri;
}
Run Code Online (Sandbox Code Playgroud)

参考文献:


Kev*_*yen 11

试试这个

    if ($host !~* ^www\.){
        rewrite ^(.*)$ https://www.yoursite.com$1;
    }
Run Code Online (Sandbox Code Playgroud)

其他方式:Nginx没有www到www

server {
  listen       80;
  server_name  yoursite.com;
  root /path/;
  index index.php;
  return       301 https://www.yoursite.com$request_uri;
}
Run Code Online (Sandbox Code Playgroud)

和www到没有www

server {
  listen       80;
  server_name  www.yoursite.com;
  root /path/;
  index index.php;
  return       301 https://yoursite.com$request_uri;
}
Run Code Online (Sandbox Code Playgroud)

  • 有人说"如果地点是邪恶的".您可以放心地将if放入服务器块 (4认同)

Rav*_*hia 11

将非www重定向到www

对于单域:

server {
        server_name example.com;
        return 301 $scheme://www.example.com$request_uri;
}
Run Code Online (Sandbox Code Playgroud)

对于所有域名:

server {
        server_name "~^(?!www\.).*" ;
        return 301 $scheme://www.$host$request_uri;
}
Run Code Online (Sandbox Code Playgroud)

将www重定向到非www for Single Domain:

server {
        server_name www.example.com;
        return 301 $scheme://example.com$request_uri;
}
Run Code Online (Sandbox Code Playgroud)

对于所有域名:

server {
         server_name "~^www\.(.*)$" ;
         return 301 $scheme://$1$request_uri ;
}
Run Code Online (Sandbox Code Playgroud)


小智 8

独特格式:

server {
  listen 80;
  server_name "~^www\.(.*)$" ;
  return 301 https://$1$request_uri ;
}
Run Code Online (Sandbox Code Playgroud)


Mao*_*dok 5

location / { 
    if ($http_host !~ "^www.domain.com"){ 
        rewrite ^(.*)$ $scheme://www.domain.com/$1 redirect; 
    } 
}
Run Code Online (Sandbox Code Playgroud)


Dra*_*kes 5

如果您不想对域名进行硬编码,则可以使用此重定向块。没有前导 www 的域被保存为$domain可以在重定向语句中重用的变量。

server {
    ...
    # Redirect www to non-www
    if ( $host ~ ^www\.(?<domain>.+) ) {
       rewrite ^/(.*)$ $scheme://$domain/$1;
    }
}
Run Code Online (Sandbox Code Playgroud)

REF:在 nginx 中使用正则表达式重定向子域