ドメインが example.com
と www.example.com
の2つがあり、これらを統一するときのベストプラクティスです
方法としてはnginx.confにリダイレクトのルールを書きますが、その書き方について公式から言及されていました
https://mogile.web.fc2.com/nginx_wiki/start/topics/tutorials/config_pitfalls/#server-name-if
まず、nginxのconfig内ではifを使ってはいけないそうです。禁止というわけではありませんが、極力使うなと書いてあります。
複数のserver_nameを指定する
example.com
とwww.example.com
が存在するときに、どちらにアクセスしてもexample.com
が表示されるようにしたいとします。
その場合server_nameを2つ書くわけですが、見た目をスッキリさせる目的等で以下のように書いてしまうことがあります。
server { server_name example.com *.example.com; if ($host ~* ^www\.(.+)) { set $raw_domain $1; rewrite ^/(.*)$ $raw_domain/$1 permanent; } # [...] } }
これはserver_name
を2つ指定して$host
で判定してリダイレクトするというものです。
しかしこれは先程のifは邪悪で言われたifを使ってしまっています。
なぜだめなのかというと、その理由も書いてあります。
これには実際のところ3つの問題があります。1つ目はif です。私達が今心配しているのはそれです。なぜこれが悪いのか?Ifは邪悪 を読みましたか?NGINXがリクエストを受信すると – 要求されたサブドメインが何であっても、それが www.example.com あるいは単なる example.com であっても – こif ディレクティブは常に評価されます。全てのリクエストについてHostヘッダをチェックするようにNGINXに夜言う窮しているため、非常に非効率です。それはさけなければなりません。代わりに、以下の例のように2つのserverディレクティブを使います。
3つといいつつ1つしか教えてくれませんでしたが、つまり 全てのリクエストに対して毎回ifで処理が入ってしまうから、やめたほうがいいよ という感じでしょうか
良い書き方は以下です
server { server_name www.example.com; return 301 $scheme://example.com$request_uri; } server { server_name example.com; # [...] }
上記のようにすることで、server_name
ごとになにが処理されるかわかりやすいです。
$scheme
が使われていますが、これはhttpとhttpsをハードコートしないようにするために書かれているそうです。
意図的にhttps
にアクセスさせたい場合はreturn 301 https://example.com$request_uri
としても良いと思います(個人の意見)
リダイレクトの方法
リダイレクトの方法で正規表現を使う方法がよくあります
rewrite
です。
しかしこれは公式ではあまり使わないほうが良いとされています。
理由は 正規表現で混乱するから だそうです
悪い:
rewrite ^/(.*)$ http://example.com/$1 permanent;良い:
rewrite ^ http://example.com$request_uri? permanent;より良い:
return 301 http://example.com$request_uri;上を見てください。そしてここに戻ってください。そして上に行き、ここに戻ってください。OK. 最初のrewriteは完全なURIから最初のスラッシュを引いたものをキャプチャします。組み込み変数 $request_uri を使うことで、キャプチャやマッチングを多少なりとも効果的に回避できます。
正規表現を使ってややこしくするより、return
を書いたほうがわかりやすいということですね