[redirect] Nginx no-www to www 및 www to no-www

튜토리얼에 따라 랙 공간 클라우드에서 nginx를 사용 하고 있으며 그물을 검색했지만 지금까지이를 정렬 할 수 없습니다.

SEO 및 기타 이유로 www.mysite.com이 .htaccess에서 정상적으로 mysite.com으로 이동하기를 원합니다.

/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.com 192.192.6.8 A type at 300 seconds
www.site.com 192.192.6.8 A type at 300 seconds

(예제 IP 및 폴더는 예를 들어 향후 사람들을 돕기 위해 사용되었습니다). 우분투 11을 사용합니다.



답변

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

        }
}

참고 : 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#
}

따라서 두 개의 서버 코드가 필요합니다.

nginx 리디렉션을 사용하여 URL에 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#
}

당신이 상상할 수 있듯이, 이것은 정반대이며 첫 번째 예와 같은 방식으로 작동합니다. 이렇게하면 완벽한 파마 리디렉션 및 이동으로 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;
       }
}


답변

실제로 다시 작성하지 않아도됩니다.

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가 아닌 ​​상대방에게 리디렉션하십시오.

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

$scheme변수는 포함 http서버는 포트 80 (기본값)에서 수신되는 경우와는 포함하지 않는 옵션들을 ssl키워드를. 변수를 사용하지 않으면 성능이 향상되지 않습니다.

HSTS 헤더는 암호화되지 않은 연결을 통해 전송되어서는 안되므로 HSTS를 사용하는 경우 더 많은 서버 블록이 필요합니다. 따라서 리디렉션이있는 암호화되지 않은 서버 블록과 리디렉션 및 HSTS 헤더가있는 암호화 된 서버 블록이 필요합니다.

모든 것을 SSL로 리디렉션하십시오 (IPv4, IPv6, SPDY 등을 사용하는 UNIX의 개인 구성).

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

나는 당신이 지금이 패턴을 가진 다른 화합물들을 상상할 수 있다고 생각합니다.

내 설정이 더 있습니까? 여기여기로 가십시오 .


답변

더 많은 도메인에 동일한 구성을 사용하고 싶을 수 있습니다.

다음 스 니펫은 도메인 전에 www를 제거합니다.

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


답변

두 개의 서버 블록이 필요합니다.

이것을 구성 파일에 넣으십시오. /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 (사용하려는 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)

ipv6의 경우, ipv6-address를 사용하여 AAAA 레코드 쌍을 작성하십시오.


답변

여러 www에서 no-www 서버 이름으로 사용하는 방법은 다음과 같습니다 (하위 도메인에 사용).

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


답변

  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
}

  1. 내에서 정규 표현식 사용 server_name

많은 사이트가 있고 최고의 성능을 신경 쓰지 않지만 www.접두사 와 관련하여 모든 사이트에서 동일한 정책을 갖기 를 원한다면 정규식을 사용할 수 있습니다. 별도의 방법을 사용하는 것이 가장 좋습니다 server.

https를 사용하면이 솔루션이 까다로워집니다. 제대로 작동하려면 모든 도메인 이름을 포괄 할 수있는 단일 인증서가 있어야하기 때문입니다.


wwwwwww / 전용 하나의 정규식 server모든 사이트에 대해 :

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

www비에 www전용 하나의 w / 정규식 server모든 사이트에 대해 :

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

www비에 www최선을 다하고에서 w / 정규식 server일부 사이트 :

이 도메인의 몇, 당신은 일치로이 같은 것을 사용할 수 있습니다 충당하기 위해 정규식을 제한 할 필요가있을 수있다 www.example.org, www.example.com그리고 www.subdomain.example.net:

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

nginx로 정규 표현식 테스트

pcretest시스템 에서 정규 표현식이 예상대로 작동하는지 테스트 할 수 있습니다 . 이는 pcrenginx가 정규 표현식에 사용하는 것과 정확히 동일한 라이브러리입니다.

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

“Host”헤더에 후행 점이있는 경우 nginx 서버 이름 정규식에 따라 nginx가 이미 처리하므로 후행 점 또는 대소 문자를 걱정할 필요가 없습니다 .


  1. if기존 server/ HTTPS 내에 뿌 립니다 :

이 최종 솔루션은 일반적으로 모범 사례로 간주되지는 않지만 여전히 작동하고 작동합니다.

실제로 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;
}

단일 선호 도메인 하드 코딩

단일 도메인에서 server사용할 수 있는 여러 도메인 간의 일관성뿐만 아니라 약간의 성능을 원한다면 단일 단일 도메인 을 명시 적으로 하드 코딩하는 것이 좋습니다.

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

참고 문헌 :


답변

이 솔루션은 제 개인적인 경험에서 비롯됩니다. S3 “Host”헤더 정책 과 일치 non-www하도록 www도메인 이름으로 리디렉션 하기 위해 여러 Amazon S3 버킷과 하나의 서버를 사용했습니다 .

nginx 서버에 다음 구성을 사용했습니다 .

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

이는 서버를 가리키는 모든 도메인 이름과 일치하지만 www.로 리디렉션됩니다 www.<domain>. 같은 방식으로에서 (으) www로 반대 리디렉션을 수행 할 수 있습니다 non-www.