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を設定する方法 を参考にしてください。
関連記事: