Nginx no-www 到 www 以及 www 到 no-www

发布于 2024-12-12 18:02:55 字数 1224 浏览 2 评论 0 原文

我正在 Rackspace 云上使用 nginx教程并在网上进行了搜索,但到目前为止还无法对此进行排序。

出于 SEO 和其他原因,我希望 www.mysite.example 在 .htaccess 中正常访问 mysite.example

我的 /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;
       }

我也尝试过

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;
       }

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

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

我的 DNS 设置为标准:(

site.example 192.192.6.8 A type at 300 seconds
www.site.example 192.192.6.8 A type at 300 seconds

示例 IP 和文件夹已用作示例并为将来的人们提供帮助)。我使用Ubuntu 11。

I am using nginx on Rackspace cloud following a tutorial and having searched the net and so far can't get this sorted.

I want www.mysite.example to go to mysite.example as normal in .htaccess for SEO and other reasons.

My /etc/nginx/sites-available/www.example.com.vhost config:

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;
       }

I have also tried

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;
       }

I also tried. Both the second attempts give redirect loop errors.

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

My DNS is setup as standard:

site.example 192.192.6.8 A type at 300 seconds
www.site.example 192.192.6.8 A type at 300 seconds

(example IPs and folders have been used for examples and to help people in future). I use Ubuntu 11.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(20

风启觞 2024-12-19 18:02:55

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;
    ...
}

HTTPS 解决方案

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

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://< /code> 在我的解决方案中,因为我们使用负载均衡器并且我们的 https:// 服务器是高流量 SSL 支付服务器:我们不会混合使用 https:// 和 http://。


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

使用 Nginx 重定向从 URL 中去除 www

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 ,您可以使用这个:

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 并显示目录!

下面显示了我的一些代码,以便更好地查看:

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;
       }
}

HTTP Solution

From the documentation, "the right way is to define a separate server for 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;
    ...
}

HTTPS Solution

For those who want a solution including https://...

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...

        }
}

Note: I have not originally included https:// in my solution since we use loadbalancers and our https:// server is a high-traffic SSL payment server: we do not mix https:// and http://.


To check the Nginx version, use nginx -v.

Strip www from URL with Nginx redirect

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

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

So you need to have TWO server codes.

Add the www to the URL with Nginx redirect

If what you need is the opposite, to redirect from domain.example to www.domain.example, you can use this:

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#
}

As you can imagine, this is just the opposite and works the same way the first example. This way, you don't get SEO marks down, as it is complete perm redirect and move. The no WWW is forced and the directory shown!

Some of my code shown below for a better view:

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;
       }
}
晚风撩人 2024-12-19 18:02:55

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

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...
}

因为我的答案得到了越来越多的支持,但上述情况也是如此。您永远不应该在这种情况下使用重写。为什么?因为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...
}

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

请注意,如果使用 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...
}

我想您现在可以自己想象具有此模式的其他组合。

更多我的配置?转到此处

Actually you don't even need a rewrite.

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...
}

As my answer is getting more and more up votes but the above as well. You should never use a rewrite in this context. Why? Because nginx has to process and start a search. If you use return (which should be available in any nginx version) it directly stops execution. This is preferred in any context.

Redirect both, non-SSL and SSL to their non-www counterpart:

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...
}

The $scheme variable will only contain http if your server is only listening on port 80 (default) and the listen option does not contain the ssl keyword. Not using the variable will not gain you any performance.

Note that you need even more server blocks if you use HSTS, because the HSTS headers should not be sent over non-encrypted connections. Hence, you need unencrypted server blocks with redirects and encrypted server blocks with redirects and HSTS headers.

Redirect everything to SSL (personal config on UNIX with 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...
}

I guess you can imagine other compounds with this pattern now by yourself.

More of my configs? Go here and here.

终难遇 2024-12-19 18:02:55
  1. 最佳实践:使用硬编码的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
}

  1. server_name中使用正则表达式

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

请注意,如果您使用 https,此解决方案会变得很棘手,因为如果您希望此解决方案正常工作,您必须拥有一个证书来覆盖您的所有域名。


wwwwww,在所有站点的专用单个服务器中使用正则表达式:

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

www 到非< code>www w/ 正则表达式位于所有站点的专用单个 server 中:

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

www 到非 www w/ 正则表达式仅适用于某些网站的专用服务器

可能需要限制正则表达式仅覆盖几个域,那么您可以使用类似的内容来仅匹配 www.example.orgwww.example.comwww .subdomain.example.net

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

使用 nginx 测试正则表达式

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

% 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 已经处理了它,按照 当“Host”标头有尾随时,nginx 服务器名称正则表达式点


  1. 在现有服务器/HTTPS中撒入if

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

事实上,如果您使用 HTTPS,那么最终的解决方案可能会更容易维护,因为您不必在不同的 server 定义之间复制粘贴一大堆 ssl 指令,并且可以仅将片段放入所需的服务器中,从而更轻松地调试和维护站点。


wwwwww

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

www到非www

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

硬编码单个首选域

如果你想要一点为了提高性能,以及单个服务器可能使用的多个域之间的一致性,显式硬编码单个首选域可能仍然有意义:

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

参考:

  1. Best Practice: separate server w/ hardcoded server_name

Best practice with nginx is to use a separate server for a redirect like this (not shared with the server of your main configuration), to hardcode everything, and not use regular expressions at all.

It may also be necessary to hardcode the domains if you're using HTTPS, because you have to know upfront which certificates you'll be providing.

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. Using Regular Expressions within server_name

If you have a number of sites, and don't care for the most ultimate performance, but want every single one of them to have the same policy in regards to the www. prefix, then you can use regular expressions. The best practice of using a separate server would still stand.

Note that this solution gets tricky if you use https, as you must then have a single certificate to cover all of your domain names if you want this to work properly.


non-www to www w/ regex in a dedicated single server for all sites:

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

www to non-www w/ regex in a dedicated single server for all sites:

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

www to non-www w/ regex in a dedicated server for some sites only:

It may be necessary to restrict the regex to cover only a couple of domains, then you can use something like this to only match www.example.org, www.example.com and www.subdomain.example.net:

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

Testing Regular Expressions w/ nginx

You can test that the regex works as expected with pcretest on your system, which is the exact same pcre library that your nginx will be using for regular expressions:

% 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> 

Note that you don't have to worry about trailing dots or case, as nginx already takes care of it, as per nginx server name regex when "Host" header has a trailing dot.


  1. Sprinkle if within existing server / HTTPS:

This final solution is generally not considered to be the best practice, however, it still works and does the job.

In fact, if you're using HTTPS, then this final solution may end up easier to maintain, as you wouldn't have to copy-paste a whole bunch of ssl directives between the different server definitions, and could instead place the snippets only into the needed servers, making it easier to debug and maintain your sites.


non-www to www:

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

www to non-www:

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

hardcoding a single preferred domain

If you want a little bit more performance, as well as consistency between multiple domains a single server may use, it might still make sense to explicitly hardcode a single preferred domain:

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

References:

过去的过去 2024-12-19 18:02:55

您可能会发现您想要对更多域使用相同的配置。

以下代码片段删除任何域之前的 www:

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

You may find out you want to use the same config for more domains.

Following snippet removes www before any domain:

if ($host ~* ^www\.(.*)$) {
    rewrite / $scheme://$1 permanent;
}
删除→记忆 2024-12-19 18:02:55

您需要两个服务器块。

将这些放入您的配置文件中,例如 /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
}

第一个服务器块将包含重定向任何带有“www”前缀的请求的指令。它侦听对带有“www”前缀的 URL 的请求并进行重定向。

它没有任何其他作用。

第二个服务器块将保存您的主要地址 - 您要使用的 URL。所有其他设置都位于此处,例如 rootindexlocation 等。检查默认文件以了解可以包含在服务器块中的其他设置。

服务器需要两条 DNS A 记录。

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

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

对于 ipv6,使用 your-ipv6-address 创建一对 AAAA 记录。

You need two server blocks.

Put these into your config file eg /etc/nginx/sites-available/sitename

Let's say you decide to have http://example.com as the main address to use.

Your config file should look like this:

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
}

The first server block will hold the instructions to redirect any requests with the 'www' prefix. It listens to requests for the URL with 'www' prefix and redirects.

It does nothing else.

The second server block will hold your main address — the URL you want to use. All other settings go here like root, index, location, etc. Check the default file for these other settings you can include in the server block.

The server needs two DNS A records.

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

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

For ipv6 create the pair of AAAA records using your-ipv6-address.

ぺ禁宫浮华殁 2024-12-19 18:02:55

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

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

Here's how to do it for multiple www to no-www server names (I used this for subdomains):

server {
        server_name 
             "~^www\.(sub1.example.com)$"
             "~^www\.(sub2.example.com)$"
             "~^www\.(sub3.example.com)$";
         return 301 $scheme://$1$request_uri ;
}
分開簡單 2024-12-19 18:02:55

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

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

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

    # Regular location configs...
}

如果您更喜欢非HTTPS、非www到HTTPS、www同时重定向:

server {
    listen 80;

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

    rewrite ^ https://$host$request_uri permanent;
}

I combined the best of all the simple answers, without hard-coded domains.

301 permanent redirect from non-www to www (HTTP or HTTPS):

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

    # Regular location configs...
}

If you prefer non-HTTPS, non-www to HTTPS, www redirect at the same time:

server {
    listen 80;

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

    rewrite ^ https://$host$request_uri permanent;
}
勿忘初心 2024-12-19 18:02:55

这个解决方案来自我的个人经验。我们使用多个 Amazon S3 存储桶和一台服务器将 非 www 重定向到 www 域名以匹配 S3​​“主机”标头策略

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

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

这匹配指向服务器的所有域名,以 www. 开头,并重定向到 www.。以同样的方式,您可以执行从 wwwnon-www 的相反重定向。

This solution comes from my personal experience. We used several Amazon S3 buckets and one server for redirecting non-www to www domain names to match S3 "Host" header policy.

I used the following configuration for nginx server:

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

This matches all domain names pointed to the server starting with whatever but www. and redirects to www.<domain>. In the same manner you can do opposite redirect from www to non-www.

久光 2024-12-19 18:02:55

试试这个

if ($host !~* ^www\.){
    rewrite ^(.*)$ https://www.yoursite.example$1;
}

其他方式:
Nginx no-www 到 www

server {
  listen       80;
  server_name  yoursite.example;
  root /path/;
  index index.php;
  return       301 https://www.yoursite.example$request_uri;
}

以及 www 到 no-www

server {
  listen       80;
  server_name  www.yoursite.example;
  root /path/;
  index index.php;
  return       301 https://yoursite.example$request_uri;
}

try this

if ($host !~* ^www\.){
    rewrite ^(.*)$ https://www.yoursite.example$1;
}

Other way:
Nginx no-www to www

server {
  listen       80;
  server_name  yoursite.example;
  root /path/;
  index index.php;
  return       301 https://www.yoursite.example$request_uri;
}

and www to no-www

server {
  listen       80;
  server_name  www.yoursite.example;
  root /path/;
  index index.php;
  return       301 https://yoursite.example$request_uri;
}
冷默言语 2024-12-19 18:02:55

将非 www 重定向到 www

对于单个域:

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

对于所有域:

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

将 www 重定向到非 www
对于单个域:

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

对于所有域:

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

Redirect non-www to www

For Single Domain :

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

For All Domains :

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

Redirect www to non-www
For Single Domain:

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

For All Domains :

server {
         server_name "~^www\.(.*)$" ;
         return 301 $scheme://$1$request_uri ;
}
计㈡愣 2024-12-19 18:02:55

独特的格式:

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

Unique format:

server {
  listen 80;
  server_name "~^www\.(.*)$" ;
  return 301 https://$1$request_uri ;
}
温馨耳语 2024-12-19 18:02:55

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

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

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

If you don't want to hardcode the domain name, you can use this redirect block. The domain without the leading www is saved as variable $domain which can be reused in the redirect statement.

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

REF: Redirecting a subdomain with a regular expression in nginx

來不及說愛妳 2024-12-19 18:02:55
location / {
    if ($http_host !~ "^www.domain.example"){
        rewrite ^(.*)$ $scheme://www.domain.example$1 redirect;
    }
}
location / {
    if ($http_host !~ "^www.domain.example"){
        rewrite ^(.*)$ $scheme://www.domain.example$1 redirect;
    }
}
埋情葬爱 2024-12-19 18:02:55

不确定是否有人注意到返回 301 可能是正确的,但浏览器对此感到窒息,

rewrite ^(.*)$ https://yoursite.example$1;

因为它的速度比:

return 301 $scheme://yoursite.example$request_uri;

not sure if anyone notice it may be correct to return a 301 but browsers choke on it to doing

rewrite ^(.*)$ https://yoursite.example$1;

is faster than:

return 301 $scheme://yoursite.example$request_uri;
心病无药医 2024-12-19 18:02:55

Ghost 博客

为了让 nginx 推荐使用 return 301 $scheme://example.com$request_uri; 与 Ghost 一起使用的方法,您需要在主服务器块中添加:

proxy_set_header    X-Real-IP           $remote_addr;
proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
proxy_set_header    Host                $http_host;
proxy_set_header    X-Forwarded-Proto   $scheme;
proxy_set_header    X-NginX-Proxy       true;

proxy_pass_header   X-CSRF-TOKEN;
proxy_buffering     off;
proxy_redirect      off;  

Ghost blog

in order to make nginx recommended method with return 301 $scheme://example.com$request_uri; work with Ghost you will need to add in your main server block:

proxy_set_header    X-Real-IP           $remote_addr;
proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
proxy_set_header    Host                $http_host;
proxy_set_header    X-Forwarded-Proto   $scheme;
proxy_set_header    X-NginX-Proxy       true;

proxy_pass_header   X-CSRF-TOKEN;
proxy_buffering     off;
proxy_redirect      off;  
梨涡 2024-12-19 18:02:55

我的配置是 - Nginx + tomcat 9 + Ubuntu 20.04 + spring boot 应用程序
上面的所有答案都不适合我 - 也不适用于 Nginx 文件中的上游符号 - 所以我更改了我的设置,

感谢上帝的 certbot - 这个实用程序非常有用,它为您的网站生成基本文件,然后我添加了我的更改 - 重定向https://www.example.comhttp://www.example.com 仅限一个 https://example.com

server {
if ($host = www.example.com) {
    return 301 https://example.com$request_uri;
}
    root /var/www/example.com/html;
    index index.html index.htm index.nginx-debian.html;

    server_name example.com www.example.com;

    location / {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header Host $http_host;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_pass http://127.0.0.1:8080; # This is upstream name, note the variable $scheme in it
      proxy_redirect off;
    }
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
    if ($host = www.example.com) {
        return 301 https://example.com$request_uri;
    } # managed by Certbot
    if ($host = example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot
        listen 80;
        listen [::]:80;
        server_name example.com www.example.com;
    return 404; # managed by Certbot
}

my configuration was - Nginx + tomcat 9 + Ubuntu 20.04 + spring boot app
all answers above not working for me - also not work upstream notation in Nginx file - so I change my settings on this

thanks God for certbot - this util very helpful, it's generate base file for your site and then I added my changes - to redirect https://www.example.com, http://www.example.com to only one https://example.com

server {
if ($host = www.example.com) {
    return 301 https://example.com$request_uri;
}
    root /var/www/example.com/html;
    index index.html index.htm index.nginx-debian.html;

    server_name example.com www.example.com;

    location / {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header Host $http_host;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_pass http://127.0.0.1:8080; # This is upstream name, note the variable $scheme in it
      proxy_redirect off;
    }
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
    if ($host = www.example.com) {
        return 301 https://example.com$request_uri;
    } # managed by Certbot
    if ($host = example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot
        listen 80;
        listen [::]:80;
        server_name example.com www.example.com;
    return 404; # managed by Certbot
}
情深缘浅 2024-12-19 18:02:55
if ($host ~* ^www.example.com$) {
    return 301 $scheme://example.com$request_uri;
}
if ($host ~* ^www.example.com$) {
    return 301 $scheme://example.com$request_uri;
}
再浓的妆也掩不了殇 2024-12-19 18:02:55

使用 cloudflare 添加 CNAME 并使用此格式作为 conf 文件。

server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
    proxy_pass "http://localhost:3000/";
}}

Add CNAME with cloudflare and use this format as conf file.

server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
    proxy_pass "http://localhost:3000/";
}}
揽月 2024-12-19 18:02:55

关键是根据您的情况将所有两个或三个服务器块分开,例如,如果使用 SSL,则应该有 3 个服务器块:

第 1 块:处理 www 到非 www 重定向:

server
{
    # Redirect all requests to https://www.example.com to https://example.com
    server_name www.example.com;

    listen 80;
    listen 443 ssl; # Certbot SSL

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
    return 301 https://example.com$request_uri;
}

第 2 块:从域根提供文件的主块:

server
{
    # Handle requests for https://example.com
    server_name example.com;
    root some_path;
    access_log some_path/example.com_access.log;
    error_log some_path/example.com_error.log;
    index index.php index.html index.htm;

    ## Main public_html nginx conf
    location ~ \.php$ {
    try_files $uri =404;
    fastcgi_pass unix:/var/opt/remi/php81/run/php-fpm/www.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

第 3 块:从 http 到 https 的可选 SSL 重定向处理:

server
{
    # Redirect all HTTP traffic to HTTPS
    listen 80;
    server_name domain.com www.example.com;
    return 301 https://$host$request_uri;
}

我也遇到了麻烦,但最终想通了 从 WWW 重定向到NGINX 中的非 WWW。建议通过链接进行逐步说明。如果您有任何疑问,请告诉我。

Key is to separate all two or three server blocks depending upon your situation for example if using SSL there should be 3 server blocks:

Block 1: To handle www to non-www redirect:

server
{
    # Redirect all requests to https://www.example.com to https://example.com
    server_name www.example.com;

    listen 80;
    listen 443 ssl; # Certbot SSL

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
    return 301 https://example.com$request_uri;
}

Block 2: Main block to serve files from domain root:

server
{
    # Handle requests for https://example.com
    server_name example.com;
    root some_path;
    access_log some_path/example.com_access.log;
    error_log some_path/example.com_error.log;
    index index.php index.html index.htm;

    ## Main public_html nginx conf
    location ~ \.php$ {
    try_files $uri =404;
    fastcgi_pass unix:/var/opt/remi/php81/run/php-fpm/www.sock;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

Block 3: Optional SSL redirection handling from http to https:

server
{
    # Redirect all HTTP traffic to HTTPS
    listen 80;
    server_name domain.com www.example.com;
    return 301 https://$host$request_uri;
}

I was also having a trouble but finally figured out Redirection from WWW to NON-WWW in NGINX. Recommended to go through link as it explains step-by-step. Let me know if you have any questions.

梦亿 2024-12-19 18:02:55

如果您无法正常工作,您可能需要添加服务器的 IP 地址。例如:

server {
listen XXX.XXX.XXX.XXX:80;
listen XXX.XXX.XXX.XXX:443 ssl;
ssl_certificate /var/www/example.com/web/ssl/example.com.crt;
ssl_certificate_key /var/www/example.com/web/ssl/example.com.key;
server_name www.example.com;
return 301 $scheme://example.com$request_uri;
}

其中 XXX.XXX.XXX.XXX 是 IP 地址(显然)。

注意:必须定义 ssl crt 和密钥位置才能正确重定向 https 请求

进行更改后不要忘记重新启动 nginx:

service nginx restart

If you are having trouble getting this working, you may need to add the IP address of your server. For example:

server {
listen XXX.XXX.XXX.XXX:80;
listen XXX.XXX.XXX.XXX:443 ssl;
ssl_certificate /var/www/example.com/web/ssl/example.com.crt;
ssl_certificate_key /var/www/example.com/web/ssl/example.com.key;
server_name www.example.com;
return 301 $scheme://example.com$request_uri;
}

where XXX.XXX.XXX.XXX is the IP address (obviously).

Note: ssl crt and key location must be defined to properly redirect https requests

Don't forget to restart nginx after making the changes:

service nginx restart
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文