首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Nginx no-www to www,www to no-www

Nginx no-www to www,www to no-www
EN

Stack Overflow用户
提问于 2011-10-30 18:56:01
回答 18查看 392.1K关注 0票数 561

我正在使用Rackspace云上的nginx教程,并且已经搜索了这个网络,到目前为止还没有解决这个问题。

由于SEO和其他原因,我希望www.mysite.example能像往常一样在.htaccess上使用mysite.example

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

代码语言:javascript
复制
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;
       }

我也试过

代码语言:javascript
复制
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;
       }

我也试过了。第二次尝试都会产生重定向循环错误。

代码语言:javascript
复制
if ($host = 'www.example.com' ) {
rewrite ^ http://example.com$uri permanent;
}

我的DNS是作为标准设置的:

代码语言:javascript
复制
site.example 192.192.6.8 A type at 300 seconds
www.site.example 192.192.6.8 A type at 300 seconds

(示例in和文件夹已用于示例并在将来帮助人们)。我使用Ubuntu 11。

EN

回答 18

Stack Overflow用户

回答已采纳

发布于 2011-10-31 19:18:07

HTTP解决方案

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

代码语言:javascript
复制
server {
    listen       80;
    server_name  example.com;
    return       301 http://www.example.com$request_uri;
}

server {
    listen       80;
    server_name  www.example.com;
    ...
}

HTTPS解决方案

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

代码语言:javascript
复制
server {
        listen 80;
        server_name www.domain.example;
        # $scheme will get the http protocol
        # and 301 is best practice for tablet, phone, desktop and seo
        return 301 $scheme://domain.example$request_uri;
}

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

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

        }
}

注意:由于我们使用了负载平衡器,而且https:// server是一个高流量SSL支付服务器:我们不混合https://和http://.,所以我最初没有在解决方案中包括https://

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

重定向

代码语言:javascript
复制
server {
    server_name  www.domain.example;
    rewrite ^(.*) http://domain.example$1 permanent;
}

server {
    server_name  domain.example;
    #The rest of your configuration goes here#
}

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

用Nginx重定向将www添加到URL

如果您需要的是从domain.example重定向到www.domain.example,则可以使用以下方法:

代码语言:javascript
复制
server {
    server_name  domain.example;
    rewrite ^(.*) http://www.domain.example$1 permanent;
}

server {
    server_name  www.domain.example;
    #The rest of your configuration goes here#
}

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

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

代码语言:javascript
复制
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;
       }
}
票数 835
EN

Stack Overflow用户

发布于 2012-07-31 04:58:55

其实你根本不需要重写。

代码语言:javascript
复制
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...
}

因为我的回答是越来越多的选票,但以上也是如此。您不应该在这个上下文中使用rewrite。为什么?因为nginx必须处理并开始搜索。如果您使用return (在任何nginx版本中都可以使用),它将直接停止执行。这在任何情况下都是首选。

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

代码语言:javascript
复制
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...
}

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

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

将所有内容重定向到SSL (在UNIX上使用IPv4、IPv6、SPDY、.):

代码语言:javascript
复制
#
# 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...
}

我想你可以想象其他的化合物,现在用这个模式,现在你自己。

更多我的吐露?去这里这里

票数 435
EN

Stack Overflow用户

发布于 2019-01-23 00:37:54

  1. 最佳实践:单独的server w/硬编码server_name

使用nginx的最佳实践是使用单独的server来进行这样的重定向(不与主配置的server共享),硬编码所有内容,而根本不使用正则表达式。

如果您使用HTTPS,也可能需要对域进行硬编码,因为您必须预先知道您将提供哪些证书。

代码语言:javascript
复制
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
}
  1. server_name中使用正则表达式

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

请注意,如果使用https,则此解决方案会变得棘手,因为如果要使其正常工作,则必须有一个包含所有域名的证书。

wwwwww w/ regex的专用单一server用于所有站点:

代码语言:javascript
复制
server {
    server_name ~^(?!www\.)(?<domain>.+)$;
    return  301 $scheme://www.$domain$request_uri;
}

www到非www w/ regex在一个专用的单一server为所有站点:

代码语言:javascript
复制
server {
    server_name ~^www\.(?<domain>.+)$;
    return  301 $scheme://$domain$request_uri;
}

www到非www w/ regex的专用server仅适用于某些站点:

可能有必要限制regex只覆盖几个域,然后可以使用类似的方法来匹配www.example.orgwww.example.comwww.subdomain.example.net

代码语言:javascript
复制
server {
    server_name ~^www\.(?<domain>(?:example\.org|example\.com|subdomain\.example\.net))$;
    return  301 $scheme://$domain$request_uri;
}

测试正则表达式w/ nginx

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

代码语言:javascript
复制
% 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> 

请注意,您不必担心尾随点或情况,因为按照当“主机”头部有尾随点时,nginx服务器名regex,nginx已经处理好了。

  1. if喷洒到现有的server /HTTPS中:

这个最终的解决方案通常不被认为是最佳实践,但是,它仍然有效,并完成了工作。

事实上,如果您使用的是HTTPS,那么这个最终的解决方案可能会更容易维护,因为您不必在不同的server定义之间复制大量的ssl指令,而是可以只将代码片段放到所需的服务器中,从而更容易调试和维护站点。

wwwwww

代码语言:javascript
复制
if ($host ~ ^(?!www\.)(?<domain>.+)$) {
    return  301 $scheme://www.$domain$request_uri;
}

www到非www

代码语言:javascript
复制
if ($host ~ ^www\.(?<domain>.+)$) {
    return  301 $scheme://$domain$request_uri;
}

硬编码单个首选域

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

代码语言:javascript
复制
if ($host != "example.com") {
    return  301 $scheme://example.com$request_uri;
}

参考文献:

  • 名字
  • http://nginx.org/r/return
  • names.html
票数 65
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7947030

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档