Webサイトを運営していて、「HTTPからHTTPSに自動で転送したい」「www付きとwwwなしを統一したい」「古いURLから新しいURLにユーザーを案内したい」と思ったことはありませんか?
「Nginxのリダイレクト設定って難しそう…」「301と302って何が違うの?」「どこに書けばいいの?」と困っている方も多いはずです。
実は、Nginxのリダイレクトは、訪問者を自動的に別のURLに転送する仕組みで、HTTPS化やURL変更、SEO対策に欠かせない重要な機能なんです。まるで、引越しの際に郵便局に転送届を出すように、古いアドレスから新しいアドレスへ自動的に案内してくれるんですよ。
この記事では、Nginxでのリダイレクト設定の基本から、実践的なパターン、トラブル対処まで、初心者の方にも分かりやすく丁寧に解説していきます。
具体的な設定例をたくさん使いながら、安全で効果的なリダイレクトをマスターしていきましょう!
リダイレクトとは?その基本を知ろう

基本的な説明
リダイレクト(Redirect)は、あるURLにアクセスしたユーザーを、自動的に別のURLに転送する仕組みです。
英語の意味:
Re-direct = 再び方向付ける
役割:
- URLの変更を通知
- HTTP→HTTPSの自動転送
- www付き/なしの統一
- 旧サイトから新サイトへの誘導
身近な例で理解しよう
郵便の転送届:
引越しの際:
旧住所に届いた郵便
↓
郵便局が自動転送
↓
新住所に届く
差出人は旧住所に送っても、ちゃんと届く
Webサイトのリダイレクト:
ユーザーが古いURLにアクセス
↓
Nginxが自動転送
↓
新しいURLが表示される
ブックマークが古くても、新しいページが見られる
道路の迂回案内:
工事中の道路:
通常ルート(通行止め)
↓
「← 迂回路」の看板
↓
別ルートで目的地へ
ドライバーは自動的に正しいルートを進める
リダイレクトは、「このURLは移転しました。こちらへどうぞ!」という自動案内なんです。
リダイレクトの種類
永久リダイレクト(301 Moved Permanently):
「このページは永久に移転しました」
検索エンジン:新しいURLをインデックス
ブラウザ:次回から新しいURLに直接アクセス
一時リダイレクト(302 Found):
「このページは一時的に別の場所にあります」
検索エンジン:元のURLを保持
ブラウザ:毎回リダイレクトをチェック
HTTPステータスコードの理解
主なリダイレクトステータスコード
301 Moved Permanently(永久リダイレクト):
用途:
- ドメイン変更
- URLの恒久的な変更
- サイト移転
特徴:
- SEO評価が引き継がれる
- ブラウザにキャッシュされる
- 検索エンジンが新URLをインデックス
例:
古いサイト: old-site.com
新しいサイト: new-site.com
301で転送 → SEO評価が新サイトに移る
302 Found(一時リダイレクト):
用途:
- メンテナンス中の案内
- A/Bテスト
- キャンペーンページへの誘導
特徴:
- SEO評価は元のURLに残る
- 一時的な転送
- キャッシュされにくい
例:
通常ページ: example.com/product
キャンペーン中だけ: example.com/sale
302で転送 → キャンペーン終了後は元に戻る
307 Temporary Redirect(一時リダイレクト・HTTPメソッド保持):
用途:
- POSTリクエストを保持したい場合
- APIリダイレクト
特徴:
- HTTPメソッド(POST/GETなど)を変更しない
- より正確な一時リダイレクト
308 Permanent Redirect(永久リダイレクト・HTTPメソッド保持):
用途:
- POSTリクエストを保持したい恒久的な転送
特徴:
- HTTPメソッドを保持
- 301のHTTPメソッド保持版
ステータスコード比較表
| コード | 名称 | 種類 | HTTPメソッド | SEO | キャッシュ | 用途 |
|---|---|---|---|---|---|---|
| 301 | Moved Permanently | 永久 | 変更される可能性 | 新URLへ | される | サイト移転 |
| 302 | Found | 一時 | 変更される可能性 | 元URL保持 | されにくい | 一時的転送 |
| 307 | Temporary Redirect | 一時 | 保持 | 元URL保持 | されにくい | API転送 |
| 308 | Permanent Redirect | 永久 | 保持 | 新URLへ | される | API移転 |
Nginxでのリダイレクト基本構文
returnディレクティブ(推奨)
最もシンプルで高速:
server {
listen 80;
server_name example.com;
# 基本構文
return <ステータスコード> <URL>;
}
例:
server {
listen 80;
server_name example.com;
# 301リダイレクト
return 301 https://example.com$request_uri;
}
メリット:
- 高速(正規表現の処理が不要)
- シンプルで読みやすい
- メモリ効率が良い
rewriteディレクティブ
正規表現を使った柔軟な転送:
server {
listen 80;
server_name example.com;
# 基本構文
rewrite <パターン> <置換URL> <フラグ>;
}
例:
server {
listen 80;
server_name example.com;
# 特定のパスだけリダイレクト
rewrite ^/old-page$ /new-page permanent;
}
主なフラグ:
permanent:301リダイレクトredirect:302リダイレクトbreak:リダイレクトせずに処理を停止last:新しいlocationブロックを検索
実践例1:HTTP→HTTPSリダイレクト
最も基本的な設定
returnを使った方法(推奨):
# HTTPサーバー(80番ポート)
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
# すべてのHTTPリクエストをHTTPSへリダイレクト
return 301 https://$server_name$request_uri;
}
# HTTPSサーバー(443番ポート)
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
# SSL証明書
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# サイトのルートディレクトリ
root /var/www/example.com;
index index.html index.php;
location / {
try_files $uri $uri/ =404;
}
}
動作:
http://example.com/page
↓ 301リダイレクト
![]()
Example Domain
$hostと$server_nameの違い
$host(推奨):
return 301 https://$host$request_uri;
利点:
- リクエストのHostヘッダーをそのまま使用
- サブドメインにも対応
$server_name:
return 301 https://$server_name$request_uri;
利点:
- 設定ファイルで指定したドメインを使用
- より制御しやすい
推奨:通常は$hostを使用
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
実践例2:www付き/なしの統一
wwwなし → www付きにリダイレクト
# wwwなしをwww付きにリダイレクト
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# www付きにリダイレクト
return 301 https://www.example.com$request_uri;
}
# メインサーバー(www付き)
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
root /var/www/example.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
動作:
http://example.com → https://www.example.com
![]()
Example Domain → https://www.example.com
www付き → wwwなしにリダイレクト
# www付きをwwwなしにリダイレクト
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# wwwなしにリダイレクト
return 301 https://example.com$request_uri;
}
# メインサーバー(wwwなし)
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
root /var/www/example.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
動作:
http://www.example.com → https://example.com
![]()
Example Domain → https://example.com
実践例3:ドメイン変更
旧ドメインから新ドメインへリダイレクト
# 旧ドメイン
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name old-domain.com www.old-domain.com;
# 旧ドメインでもSSL証明書が必要
ssl_certificate /etc/nginx/ssl/old-domain.com.crt;
ssl_certificate_key /etc/nginx/ssl/old-domain.com.key;
# 新ドメインにリダイレクト(301)
return 301 https://new-domain.com$request_uri;
}
# 新ドメイン
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name new-domain.com www.new-domain.com;
ssl_certificate /etc/nginx/ssl/new-domain.com.crt;
ssl_certificate_key /etc/nginx/ssl/new-domain.com.key;
root /var/www/new-domain.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
動作:
http://old-domain.com/page → https://new-domain.com/page
![]()
https://old-domain.com/page → https://new-domain.com/page
重要:旧ドメインでもSSL証明書が必要です!
実践例4:特定のパスだけリダイレクト
単一ページのリダイレクト
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
root /var/www/example.com;
# 特定のページだけリダイレクト
location = /old-page {
return 301 /new-page;
}
# 特定のページ(拡張子付き)
location = /old-page.html {
return 301 /new-page.html;
}
# その他のページは通常通り
location / {
try_files $uri $uri/ =404;
}
}
動作:
https://example.com/old-page → https://example.com/new-page
![]()
Example Domain → 通常表示
ディレクトリ全体のリダイレクト
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
root /var/www/example.com;
# /blog/配下すべてを/news/にリダイレクト
location ^~ /blog/ {
return 301 /news$request_uri;
}
location / {
try_files $uri $uri/ =404;
}
}
動作:
https://example.com/blog/article1 → https://example.com/news/blog/article1
パスを置き換える場合:
server {
listen 443 ssl http2;
server_name example.com;
root /var/www/example.com;
# /blog/を/news/に置き換え
rewrite ^/blog/(.*)$ /news/$1 permanent;
location / {
try_files $uri $uri/ =404;
}
}
動作:
https://example.com/blog/article1 → https://example.com/news/article1
実践例5:パラメータ付きリダイレクト
クエリパラメータを保持
server {
listen 443 ssl http2;
server_name example.com;
root /var/www/example.com;
# パラメータ付きURLのリダイレクト
location = /search {
return 301 /new-search$is_args$args;
}
location / {
try_files $uri $uri/ =404;
}
}
動作:
https://example.com/search?q=nginx
↓
![]()
Example Domain
変数の説明:
$is_args:クエリ文字列がある場合は?、ない場合は空文字$args:クエリ文字列全体(?なし)$request_uri:パスとクエリ文字列の両方
パラメータを書き換え
server {
listen 443 ssl http2;
server_name example.com;
root /var/www/example.com;
# 特定のパラメータを変換
location = /old-api {
if ($arg_type = "user") {
return 301 /new-api?category=users;
}
return 301 /new-api;
}
location / {
try_files $uri $uri/ =404;
}
}
動作:
/old-api?type=user → /new-api?category=users
/old-api → /new-api
実践例6:条件付きリダイレクト

ユーザーエージェントによる振り分け
server {
listen 443 ssl http2;
server_name example.com;
root /var/www/example.com;
# モバイルデバイスを専用サイトへリダイレクト
set $mobile_redirect 0;
if ($http_user_agent ~* "mobile|android|iphone|ipad|phone") {
set $mobile_redirect 1;
}
if ($mobile_redirect = 1) {
return 301 https://m.example.com$request_uri;
}
location / {
try_files $uri $uri/ =404;
}
}
注意:Nginxのifは複雑なので、できるだけ避けるべきです。
地域によるリダイレクト(GeoIP)
# GeoIPモジュールが必要
http {
geoip_country /usr/share/GeoIP/GeoIP.dat;
server {
listen 443 ssl http2;
server_name example.com;
# 日本からのアクセスを日本語サイトへ
if ($geoip_country_code = JP) {
return 301 https://ja.example.com$request_uri;
}
# アメリカからのアクセスを英語サイトへ
if ($geoip_country_code = US) {
return 301 https://en.example.com$request_uri;
}
location / {
try_files $uri $uri/ =404;
}
}
}
実践例7:メンテナンスページへのリダイレクト
一時的なメンテナンス表示
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
root /var/www/example.com;
# メンテナンスモードフラグ
set $maintenance 0;
# メンテナンスファイルが存在する場合
if (-f /var/www/example.com/maintenance.flag) {
set $maintenance 1;
}
# 管理者IPは除外
if ($remote_addr = "123.45.67.89") {
set $maintenance 0;
}
# メンテナンスページへリダイレクト
if ($maintenance = 1) {
return 503;
}
error_page 503 @maintenance;
location @maintenance {
rewrite ^(.*)$ /maintenance.html break;
}
location / {
try_files $uri $uri/ =404;
}
}
メンテナンスの有効化/無効化:
# メンテナンスモード開始
sudo touch /var/www/example.com/maintenance.flag
sudo systemctl reload nginx
# メンテナンスモード終了
sudo rm /var/www/example.com/maintenance.flag
sudo systemctl reload nginx
実践例8:トレーリングスラッシュの統一
スラッシュを追加
server {
listen 443 ssl http2;
server_name example.com;
root /var/www/example.com;
# スラッシュがない場合は追加
rewrite ^([^.]*[^/])$ $1/ permanent;
location / {
try_files $uri $uri/ =404;
}
}
動作:
https://example.com/page → https://example.com/page/
スラッシュを削除
server {
listen 443 ssl http2;
server_name example.com;
root /var/www/example.com;
# スラッシュがある場合は削除
rewrite ^/(.*)/$ /$1 permanent;
location / {
try_files $uri $uri/ =404;
}
}
動作:
https://example.com/page/ → https://example.com/page
トラブルシューティング
問題1:リダイレクトループ
症状:
ERR_TOO_MANY_REDIRECTS
このページは動作していません
リダイレクトが繰り返し行われました
原因:
リダイレクトが無限ループになっている。
悪い例:
server {
listen 443 ssl http2;
server_name example.com;
# 間違い:HTTPSなのにHTTPSへリダイレクト
return 301 https://example.com$request_uri;
}
解決策:
# HTTPサーバー
server {
listen 80;
server_name example.com;
return 301 https://example.com$request_uri;
}
# HTTPSサーバー(リダイレクトなし)
server {
listen 443 ssl http2;
server_name example.com;
# ここではリダイレクトしない
root /var/www/example.com;
location / {
try_files $uri $uri/ =404;
}
}
問題2:リダイレクトが動作しない
症状:
設定を変更したのに、リダイレクトされない。
原因1:設定ファイルのエラー
# 設定をテスト
sudo nginx -t
出力例(エラーあり):
nginx: [emerg] unknown directive "retrun" in /etc/nginx/sites-enabled/example.com:10
nginx: configuration file /etc/nginx/nginx.conf test failed
修正して再テスト:
sudo nginx -t
出力例(成功):
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
原因2:Nginxを再起動していない
# 設定を再読み込み
sudo systemctl reload nginx
# または完全再起動
sudo systemctl restart nginx
原因3:ブラウザのキャッシュ
301リダイレクトはブラウザにキャッシュされます。
# ブラウザの対処法
1. Ctrl + Shift + R(スーパーリロード)
2. キャッシュをクリア
3. シークレットモードで確認
問題3:SSL証明書エラー
症状:
NET::ERR_CERT_COMMON_NAME_INVALID
この接続ではプライバシーが保護されません
原因:
リダイレクト先のドメインにSSL証明書がない、または不一致。
解決策:
# 旧ドメインにもSSL証明書が必要
server {
listen 443 ssl http2;
server_name old-domain.com;
# 旧ドメインの証明書
ssl_certificate /etc/nginx/ssl/old-domain.com.crt;
ssl_certificate_key /etc/nginx/ssl/old-domain.com.key;
# 新ドメインにリダイレクト
return 301 https://new-domain.com$request_uri;
}
問題4:パラメータが消える
症状:
https://example.com/search?q=test
↓ リダイレクト後
![]()
Example Domain
(?q=testが消えた!)
原因:
$request_uriの代わりに$uriを使っている。
間違った設定:
return 301 https://example.com$uri; # パラメータが消える
正しい設定:
return 301 https://example.com$request_uri; # パラメータも含まれる
または:
return 301 https://example.com$uri$is_args$args;
問題5:特定のパスがリダイレクトされない
症状:
一部のURLだけリダイレクトされない。
原因:
locationブロックの優先順位の問題。
locationの優先順位:
# 1. 完全一致(最優先)
location = /exact/path {
}
# 2. 優先プレフィックス
location ^~ /prefix/ {
}
# 3. 正規表現(大文字小文字区別)
location ~ \.php$ {
}
# 4. 正規表現(大文字小文字区別なし)
location ~* \.(jpg|png)$ {
}
# 5. プレフィックス(最低優先)
location /general/ {
}
解決例:
server {
listen 443 ssl http2;
server_name example.com;
# 特定のパスを先に処理
location = /special-page {
return 301 /new-special-page;
}
# 汎用的なルールは後に
location / {
try_files $uri $uri/ =404;
}
}
ベストプラクティス

推奨事項
1. returnを優先的に使用
# 良い例:return(高速)
return 301 https://example.com$request_uri;
# 避ける:rewrite(遅い)
rewrite ^ https://example.com$request_uri permanent;
2. 301を使用(SEO対策)
恒久的な移転には301を使います。
# サイト移転
return 301 https://new-domain.com$request_uri;
3. SSL証明書を両方に設定
リダイレクト元にもSSL証明書が必要です。
4. テストを忘れずに
# 設定テスト
sudo nginx -t
# リダイレクトの確認(curlで)
curl -I http://example.com
出力例:
HTTP/1.1 301 Moved Permanently
Server: nginx
Location: https://example.com/
5. ログを確認
# アクセスログ
sudo tail -f /var/log/nginx/access.log
# エラーログ
sudo tail -f /var/log/nginx/error.log
避けるべきこと
1. ifディレクティブの乱用
# 悪い例:複雑なif
if ($request_uri ~ "^/old") {
if ($http_user_agent ~ "Mobile") {
return 301 https://m.example.com$request_uri;
}
}
Nginxのifは「邪悪」と呼ばれています。可能な限り避けましょう。
2. 不要なリダイレクトの連鎖
# 悪い例:2段階リダイレクト
![]()
Example Domain → http://www.example.com → https://www.example.com
# 良い例:1段階リダイレクト
![]()
Example Domain → https://www.example.com
3. 302の乱用
SEOが重要な場合は、301を使います。
curlでのテスト方法
基本的なテスト
リダイレクトを追跡しない:
curl -I http://example.com
出力:
HTTP/1.1 301 Moved Permanently
Server: nginx/1.18.0
Location: https://example.com/
リダイレクトを自動追跡:
curl -L http://example.com
詳細な追跡:
curl -LI http://example.com
出力:
HTTP/1.1 301 Moved Permanently
Location: https://example.com/
HTTP/2 200
server: nginx/1.18.0
content-type: text/html
リダイレクトチェーンの確認
curl -sIL http://example.com | grep -E "HTTP|Location"
出力例:
HTTP/1.1 301 Moved Permanently
Location: https://example.com/
HTTP/2 200
よくある質問
Q1: 301と302、どちらを使うべき?
A: 恒久的な移転は301、一時的な変更は302です。
301を使う場合:
- ドメイン変更
- URL構造の恒久的な変更
- HTTP→HTTPS化
302を使う場合:
- メンテナンス中の一時的な誘導
- A/Bテスト
- 期間限定のキャンペーン
迷ったら301を使うのが安全です。
Q2: www付き/なし、どちらが良い?
A: SEO的にはどちらでも良いですが、統一が重要です。
統一することで:
- SEO評価が分散しない
- アクセス解析が正確
- ユーザーの混乱を防ぐ
Googleの推奨:どちらかに統一する
Q3: リダイレクトは何段階まで?
A: 1段階が理想、最大2段階までです。
悪い例(3段階):
http://example.com
↓
![]()
Example Domain
↓
![]()
Example Domain
良い例(1段階):
http://example.com
↓
![]()
Example Domain
多段階リダイレクトは:
- ページ表示が遅くなる
- SEO評価が下がる
- ユーザー体験が悪化
Q4: returnとrewriteの違いは?
A: returnの方がシンプルで高速です。
return:
- 高速
- シンプル
- 正規表現不要
rewrite:
- 柔軟
- 正規表現が使える
- 複雑
推奨:できるだけreturnを使用
Q5: 大量のURLをリダイレクトする方法は?
A: mapディレクティブを使います。
http {
# URLマッピング
map $uri $new_uri {
/old-page-1 /new-page-1;
/old-page-2 /new-page-2;
/old-page-3 /new-page-3;
# ... 数百個でもOK
}
server {
listen 443 ssl http2;
server_name example.com;
# マッピングがある場合はリダイレクト
if ($new_uri) {
return 301 $new_uri;
}
location / {
try_files $uri $uri/ =404;
}
}
}
まとめ
Nginxのリダイレクトは、URLの転送を自動化し、HTTPS化やURL変更、SEO対策に欠かせない重要な機能です。
この記事のポイント:
- リダイレクトはURLの自動転送機能
- 301(永久)と302(一時)を使い分ける
- returnディレクティブが推奨(高速)
- HTTP→HTTPSリダイレクトは必須
- www付き/なしは統一する
- ドメイン変更時は301を使用
- SSL証明書は両方に必要
- リダイレクトループに注意
- curlでテストできる
- SEO評価を引き継ぐには301
Nginxのリダイレクトは、Webサイト運営において非常に重要な機能です。特に、HTTP→HTTPSの自動転送は、現代のWebサイトでは必須と言えます。
設定自体はシンプルですが、ブラウザのキャッシュやSSL証明書の問題など、トラブルも起こりやすい部分です。設定変更後は必ずnginx -tでテストし、curlやブラウザで動作確認を行いましょう。
特に、301リダイレクトはブラウザに強力にキャッシュされるため、テスト時はシークレットモードやキャッシュクリアを活用してください。
Nginxのリダイレクトをマスターして、ユーザーフレンドリーでSEOに強いWebサイトを構築していきましょう!


コメント