2026年5月19日

2026年5月19日

.htaccessでHTTPからHTTPSへ301リダイレクトする方法|WordPressでの書く位置とループ対策

サイトを HTTPS で表示できるようにした後は、http:// で来たアクセスを https:// へ転送(リダイレクト)します。この記事では、Apache の .htaccess で HTTP から HTTPS へ 301 リダイレクトする書き方と、WordPress で使うときの注意点を説明します。内容は2026年10月時点の Apache 2.4 を前提にしています。

始める前に確かめること

  • HTTPS でサイトが開けること。SSL 証明書が設定されていない状態で転送すると、訪問者は証明書のエラー画面に送られます。先に https:// の URL をブラウザで開き、警告なく表示されることを確かめます
  • .htaccess でリライトが使えること。Apache の設定で、そのディレクトリに AllowOverride FileInfo(または All)が許可され、mod_rewrite が有効になっている必要があります。WordPress のパーマリンクが「投稿名」などで動いていれば、条件は満たしています
  • サーバーの管理画面に HTTPS への転送機能がないか。レンタルサーバーでは、管理画面の設定で HTTPS への転送を有効にできることがあります。その機能を使う場合は .htaccess に同じ転送を書く必要はありません。両方を設定すると、問題の切り分けが難しくなります

サーバーの設定ファイル(httpd.conf やバーチャルホストの設定)を編集できる場合は、.htaccess よりも、80番ポートのバーチャルホストに Redirect を書く方法を Apache の公式ドキュメントは勧めています。

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    Redirect permanent "/" "https://example.com/"
</VirtualHost>

以下は、設定ファイルを編集できないレンタルサーバーなどで .htaccess を使う方法です。

ステップ1:.htaccessをバックアップする

.htaccess は WordPress をインストールしたディレクトリ(wp-config.php と同じ場所)にあります。書き間違えると「500 Internal Server Error」でサイト全体が表示されなくなるため、編集の前にコピーを取ります。

cp .htaccess .htaccess.bak

FTP やサーバーの管理画面のファイルマネージャーで編集する場合は、元のファイルをパソコンにダウンロードしておきます。

ステップ2:転送のルールを書く

.htaccess の先頭、# BEGIN WordPress より前に次を書きます。

# HTTP から HTTPS への転送
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>

# BEGIN WordPress
(WordPress が書き込んだ部分。変えない)
# END WordPress

各行の意味は次のとおりです。

行 意味
RewriteEngine On この .htaccess でリライトを使う
RewriteCond %{HTTPS} !=on HTTPS ではないアクセスのときだけ、次の行を実行する
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] 同じホスト名・同じパスの https:// へ 301 で転送し、ここで処理を終える

%{REQUEST_URI} にはクエリ文字列(? の後ろ)が含まれませんが、転送先に ? を書いていなければ、元のクエリ文字列は自動で付け直されます。http://example.com/?p=123 は https://example.com/?p=123 に転送されます。

WordPressのルールより前に書く理由

# BEGIN WordPress から # END WordPress までは、WordPress が管理する部分です。パーマリンク設定を保存したときなどに WordPress が書き直すため、ここに書いた内容は消えます。また、WordPress のルールは存在しない URL をすべて index.php に渡して処理を終えるため、転送のルールを後ろに書くと、多くの URL で転送が実行されません。

ステップ3:wwwの有無も揃える(任意)

www.example.com と example.com のどちらかに揃える場合は、HTTPS への転送と1回の転送でまとめると、転送が2回続くのを避けられます。次は www なしに揃える例です(example.com は自分のドメインに置き換えます)。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [L,R=301]
</IfModule>

[OR] は「どちらかの条件に当てはまれば」、[NC] は大文字と小文字を区別しない指定です。www ありに揃える場合は、2つ目の条件を RewriteCond %{HTTP_HOST} !^www\. [NC] にし、転送先を https://www.example.com%{REQUEST_URI} にします。どちらに揃えるかは、WordPress の「設定」→「一般」の「サイトアドレス (URL)」と同じにしてください。

ステップ4:転送を確かめる

ブラウザは 301 の転送を記憶するため、書き間違えた転送が残ると、直した後もしばらく古い転送先に飛ばされます。確認には curl を使うと、ブラウザの記憶に左右されません。

curl -sI http://example.com/sample-page/?test=1 | grep -iE '^(HTTP|location)'

次のように、301 と HTTPS の転送先が表示されれば成功です。

HTTP/1.1 301 Moved Permanently
Location: https://example.com/sample-page/?test=1

続けて HTTPS の URL も確かめ、200 が返ること(もう転送されないこと)を見ます。

curl -sI https://example.com/sample-page/ | grep -iE '^(HTTP|location)'

ルールを試している間は R=301 の代わりに R=302(一時的な転送)にしておき、動作を確かめてから R=301 に変える方法もあります。302 はブラウザに記憶されにくいため、書き直しが楽になります。

ステップ5:WordPressのURLをHTTPSにする

転送だけでは、WordPress が出力するリンクや画像の URL は http:// のままです。WordPress の「設定」→「一般」で、「WordPress アドレス (URL)」と「サイトアドレス (URL)」を https:// に変えて保存します。

投稿の本文に http:// で書かれた画像やリンクが残っていると、ブラウザで「保護されていない通信」と表示されたり、画像が読み込まれなかったりします(混在コンテンツ)。WP-CLI が使える場合は、データベースのバックアップを取ったうえで次のように置き換えられます。

wp search-replace 'http://example.com' 'https://example.com' --skip-columns=guid --dry-run
wp search-replace 'http://example.com' 'https://example.com' --skip-columns=guid

--dry-run で置き換わる件数を確かめてから、--dry-run を外して実行します。混在コンテンツの探し方と直し方は HTTPS化したら mixed content エラーが出る場合の原因と直し方 で説明しています。

「リダイレクトが繰り返し行われました」と表示される場合

ブラウザに ERR_TOO_MANY_REDIRECTS が表示されてサイトが開けない場合は、転送が無限に続いています。よくある原因は、Cloudflare などの CDN や、ロードバランサーの後ろに Apache がある構成です。訪問者とは HTTPS で通信していても、CDN から Apache へは HTTP で接続しているため、Apache から見た %{HTTPS} が常に off になり、転送を繰り返します。

この場合は、CDN やロードバランサーが付ける X-Forwarded-Proto ヘッダーで判定します。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !=https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>

ただし、このヘッダーは CDN を経由しない直接のアクセスでも、送る側が自由に付けられます。CDN を使っていない場合はこの書き方にしないでください。Cloudflare では、SSL/TLS の暗号化モードを Flexible にしていると、CDN から Apache への接続が HTTP になります。サーバーに有効な証明書があるなら Full (strict) にすると、%{HTTPS} による最初の書き方のままで動きます。

WordPress 側でも、HTTPS で表示されていることを判定できないと、管理画面で転送が繰り返されることがあります。その場合は wp-config.php の /* That's all, stop editing! */ の行より前に次を書きます。

<?php
if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && 'https' === $_SERVER['HTTP_X_FORWARDED_PROTO'] ) {
	$_SERVER['HTTPS'] = 'on';
}

(<?php は wp-config.php にすでにあるので、2行目から下を追加します。)

それでも直らない場合は、サーバーの管理画面の HTTPS 転送と .htaccess の転送が重なっていないか、プラグインでも転送していないかを確かめます。詳しくは ApacheでのHTTPSリダイレクトループ修正 を参考にしてください。

うまくいかないときの確認

症状 確かめること
500 Internal Server Error になった 書き間違い。.htaccess.bak に戻して書き直す。サーバーのエラーログに原因が出る
何も転送されない ルールが # BEGIN WordPress より後ろにないか。AllowOverride でリライトが許可されているか
ERR_TOO_MANY_REDIRECTS 上の節のとおり、CDN・ロードバランサー・サーバーの管理画面の転送が重なっていないか
直したのに古い転送先に飛ぶ ブラウザが 301 を記憶している。curl で確かめるか、シークレットウィンドウで開く

まとめ

  • 先に HTTPS でサイトが開けることを確かめてから転送を設定する
  • .htaccess の # BEGIN WordPress より前に、RewriteCond %{HTTPS} !=on と RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] を書く
  • www の統一は [OR] で条件をまとめ、転送を1回で済ませる
  • curl -sI で 301 と Location を確かめる
  • WordPress の「WordPress アドレス (URL)」「サイトアドレス (URL)」を https:// にし、本文に残った http:// を置き換える
  • CDN の後ろで転送が繰り返される場合は X-Forwarded-Proto で判定し、WordPress 側にも HTTPS を伝える

HTTPS で常に接続させる HSTS を加える場合は ApacheでHSTSを設定する方法 を参考にしてください。

関連記事:

お気軽にご相談ください

お見積りへ お問い合わせへ
▲