Nginx no-www to wwwおよびwww to no-www


497

チュートリアルに従ってRackspaceクラウドでnginxを使用していて、ネットを検索したところ、これまでのところこれを並べ替えることができません。

www.mysite.comにSEOやその他の理由で.htaccessで通常どおりmysite.comにアクセスしてもらいたい。

私の/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;
       }

私も試しました

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

私も試しました。2回目の試行ではリダイレクトループエラーが発生します。

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とフォルダーは、例として、また将来の人々の助けとして使用されています)私はUbuntu 11を使用しています。


1
WordPressのWebサイトを使用している場合はDashboard > Settings > General Settings、を確認wwwし、WordPressのアドレス/サイトのアドレスのURL にが含まれていないことを確認してください。nginxの設定方法に関係なく、これらのURLにwwwが含まれている場合、wwwが含まれているURLにリダイレクトされます。
Abhinav Sood、

回答:


792

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

したがって、2つのサーバーコードが必要です。

nginxリダイレクトでwwwをURLに追加します

必要なものが逆の場合、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;
       }
}

3
@pukよろしくお願いします。Nginxは素晴らしいですが、サーバーのバージョン、OS、サーバーのハードウェアの変更に合わせて最新の状態を維持できる優れたドキュメントは、かなり面倒です。RackSpaceクラウドバージョンをサポートしているhowtoforge.comが私に役立つ最高のリソースです。上記のコマンドのいくつかは、それ以降のバージョンでは機能しません。しかし、このnginx / 0.8.54-私を信じて、最高のnginxサーバー)アップグレードまたは更新する必要はありません。正常に動作します。1日に平均100,000のユニークヒットがあり、1日あたりのトランザクション数は4200です。NginxはRAPIDです。トラフィックのないサイトを使用するようなものです。
TheBlackBenzKid

17
のように、書き換えはリターンになるはずreturn 301 $scheme://domain.com$request_uri;です。パターンをキャプチャする必要はありません。Nginxの落とし穴を
Roberto

4
@TheBlackBenzKid申し訳ありませんが、何かを見逃している可能性がありますが、更新されたソリューションが機能していません。80番をリッスンしているからです-これで、HTTPだけがこれに一致すると言っています。HTTPとHTTPSに同じ構成が使用されている場合、リッスンするポートがさらに必要です...または?しかし、間違いなく私を助けてくれました、+ 1。返信ありがとうございます。乾杯。
tomis

3
@TheBlackBenzKidただのメモでした。私は実用的な解決策を見つけました。この例では、Listen 443のみを追加して完全に機能させる必要があります。
tomis

2
答えは間違っています。すべてのサブドメインをwwwにリダイレクトします。
r3wt 2015

398

実際には、書き換えさえ必要ありません。

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このコンテキストでは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...
}

この$scheme変数はhttp、サーバーがポート80(デフォルト)のみをlistenしており、listenオプションに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...
}

私はあなたが今このパターンを持つ他の化合物を自分で想像できると思います。

私の構成の詳細?ここここに行きます


3
HSTSを使用している場合、Chromeはあなたのwwwドメインにアクセスできないはずです。できるだけ多くの詳細を記載した新しい質問を開いてください。お手伝いします(質問へのURLをコメントとしてここに投稿できます)。
Fleshgrinder 2014

1
@Fleshgrinderセットアップを実装しようとしていますが、stackoverflow.com / questions / 29451409 /…で次の問題が発生しています。
YPCrumble 2015

4
2番目のブロック「非SSLとSSLの両方を非www対応にリダイレクトする:」では、ブラウザがwww.example.comの証明書を確認してから例にリダイレクトする必要があるため、両方のサーバーブロックにSSLディレクティブが必要です。 .com。
Jeff Tsay 2015

1
もちろん、私はそれとHSTSについての短い情報を追加しました。
Fleshgrinder、2015

1
@YPCrumbleはい、この方法の方がはるかに高速です。これは、各リクエストで正規表現マッチングを実行しないためです。リダイレクトする必要があることがわかっている場合にのみリダイレクトします。チェックなし、検証なし、なし:リダイレクトのみ。=)
Fleshgrinder 2018年

37

より多くのドメインに同じ設定を使用したい場合があります。

次のスニペットは、ドメインの前のwwwを削除します。

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

7
この方法は、専用サーバーブロックよりも優れています。変更http$scheme
ck_

2
はるかに良いですが、多くの人がこのタスクの構成にドメインをハードコード化するとは信じられません。
MrYellow 2015年

1
@Oliそのリンクでは(現在のところ)パフォーマンスについて言及されていませんが、100%安全ではありません。それは、「ロケーションコンテキストの場合に内部で実行できる唯一の100%安全なものは、次のとおりです」return ...およびrewrite ... last「」です。パフォーマンスの問題への更新されたリンクはありますか?
アダム

1
これは私にはうまくいきませんでした。無効な応答を示すブラウザーでエラーが発生し続けました。
Nico Brenner、

1
残念ながら、「if」なしの方法は見つかりませんでした。多くのドメインで同じ構成を使用していますが、ドメイン名をハードコーディングすることはできません。どんな提案/コメントも大歓迎です!
MartinHöger18年

27

2つのサーバーブロックが必要です。

これらを設定ファイルに入れてください。 /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のリクエストをリッスンしてリダイレクトします。

それ以外には何もしません。

2番目のサーバーブロックは、メインアドレス(使用するURL)を保持します。他のすべての設定はここのように行くrootindexlocationサーバー・ブロックに含めることができ、これらの他の設定はデフォルトのファイルをチェックし、など。

サーバーには2つの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レコードのペアを作成します。


23

wwwからno-wwwまでの複数のサーバー名に対してこれを行う方法は次のとおりです(これをサブドメインに使用しました)。

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

20
  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を使用する場合、すべてのドメイン名をカバーする単一の証明書が必要になるため、このソリューションはトリッキーになります。


wwwwwwのw /専用のシングルでの正規表現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専用でワット/正規表現serverだけでいくつかのサイトのために:

その後、あなただけ一致させるために、このようなものを使用することができ、カバーにドメインの唯一のカップルを正規表現を制限する必要があるかもしれない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システムで期待どおりに機能することをテストできます。これは、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> 

「ホスト」ヘッダーに末尾のドットがある場合、nginxサーバー名の正規表現に従って、nginxはすでにそれを処理するため、末尾のドットや大文字小文字を気にする必要がないことに注意してください。


  1. if既存のserver/ HTTPS 内に振りかける:

この最終的なソリューションは、一般的にベストプラクティスとは見なされていませんが、それでも機能し、機能します。

実際、HTTPSを使用している場合、異なるserver定義間で一連のsslディレクティブ全体をコピーして貼り付ける必要がなく、代わりにスニペットのみを配置できるので、この最終的なソリューションは維持しやすくなる可能性があります。必要なサーバー。サイトのデバッグと保守を容易にします。


wwwwww

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

wwwwww- へ:

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

単一の優先ドメインをハードコーディングする

もう少しパフォーマンスが必要な場合、および単一のドメインserverが使用する複数のドメイン間の一貫性が必要な場合でも、単一の優先ドメインを明示的にハードコードすることは理にかなっています。

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

参照:


16

この解決策は私の個人的な経験に基づいています。複数のAmazon S3バケットと1つのサーバーを使用してnon-wwwwwwドメイン名にリダイレクトし、S3の「ホスト」ヘッダーポリシーに一致させました

nginxサーバーには次の構成を使用しました。

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

これは、すべてのドメイン名は何でもしかしで始まるサーバーを指摘一致するwww.とリダイレクトしますwww.<domain>。同じ方法で、からwwwへの逆のリダイレクトを行うことができますnon-www


httpsはどうですか?注:HTTPS NEED証明書
Toskan

ここではHTTPSについてはまったく問題ありません。後はlisten 80あなたが追加する必要がありlisten 443 ssl、その後、ssl_certificateおよびssl_certificate_keyディレクティブ。
VisioN 2017

今日誰もhttpを使用していません。私はグーグルでトップリストのガイドを読んでいましたがlisten 443 ssl 、証明書が欠落している行が追加されただけの例が示されていました その文句を言わない仕事といくつかの深刻な頭痛を引き起こしています。
トスカン2017

どのガイドについて話しているのかわかりません。私はこの構成をほぼ3年間正常に機能させています。昨年、SSLのサポートを追加しましたが、期待どおりに動作します。そしてもちろん、秘密鍵を手元に置いた証明書が必要です。
VisioN 2017

これはwwwを除くすべてのサブドメインを破壊しますよね?
メタグラファー2018年

15

ハードコーディングされたドメインなしで、すべての単純な答えの中で最高のものを組み合わせました。

www以外からwwwへの301永久リダイレクト(HTTPまたはHTTPS):

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

11

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

あなたは間の区別を提供できる80443
Hassan Baig 2017

1
listenディレクティブなしで動作するようです(nginx 1.4.6)。
イブラヒム

11

これを試して

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

他の方法:Nginx no-www to www

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

そしてwwwからwwwへ

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

著者がnginxでifステートメントを提供し、それを人々にそれを避けるように言ったのはなぜですか?私には軽快に聞こえます。
Greg Smethells、2015年

4
「ロケーションのIFが悪かった」とあります。サーバーブロックに安全に配置できます
Kukunin '

上記のリンクからの直接の引用...ロケーションコンテキストの場合に内部で実行できる唯一の100%安全なことは、次のとおりです。書き換え...最後;
Justin E

8

ユニークなフォーマット:

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

1
:あなたはそれをこのように書くことによって、それは一般的なことができます server { server_name "~^www\.(.*)$" ; return 301 $scheme://$1$request_uri ; }
Ramast


3

301を返すのは正しいかもしれないと誰かが気づいたかどうかはわかりませんが、ブラウザはそれを実行するために窒息しています

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

より高速です:

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


1
私のコメントは、nginx側の効率ではないブラウザに向けられました!rewiting時にリダイレクトして、ブラウザは1つの要求対2つの要求を作る
スティーブン・

2

ゴーストブログ

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;  

2

ドメイン名をハードコーディングしたくない場合は、このリダイレクトブロックを使用できます。先頭にwwwがないドメインは変数として保存$domainされ、リダイレクトステートメントで再利用できます。

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

REF:nginxで正規表現を使用してサブドメインをリダイレクトする


0
if ($host ~* ^www.example.com$) {
    return 301 $scheme://example.com$request_uri;
}

-6

これがうまくいかない場合は、サーバーの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アドレスです。

注:httpsリクエストを適切にリダイレクトするには、ssl crtとキーの場所を定義する必要があります

変更を行った後は、nginxを再起動することを忘れないでください。

service nginx restart

3
/etc/init.d/nginx reloadreloadダウンタイムを引き起こさないサーバーも使用できます。
TheBlackBenzKid
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.