エラーの内容
SSL証明書をインストールしてWordPressサイトをHTTPSに切り替えた後、ブラウザのコンソールに次のような警告が表示されます:
Mixed Content: The page at 'https://example.com' was loaded over HTTPS,
but requested an insecure stylesheet 'http://example.com/wp-content/themes/style.css'
Mixed Content: The page at 'https://example.com' was loaded over HTTPS,
but requested an insecure image 'http://example.com/wp-content/uploads/2024/01/photo.jpg'
ブラウザがこれらのアセットをブロックするため、南京錠アイコンが消えるか警告の三角マークが表示され、ページの一部が崩れます。
根本原因
WordPressがデータベースに保存するすべてのURL(サイトアドレス、画像パス、投稿リンク)は、インストール時にhttp://として書き込まれます。後からHTTPSに切り替えても、これらのエントリは自動的に更新されません。
ページ自体はhttps://で読み込まれますが、埋め込みリソースは依然としてhttp://を参照しています。ブラウザはセキュアなページ上でこれらの安全でないリソースをブロックします。これが混在コンテンツエラーの原因です。
古いURLは主に3か所に潜んでいます:
- WordPressデータベース —
wp_options(サイトURL、ホームURL)とwp_posts(ハードコードされたURLを含む投稿コンテンツ) wp-config.php— URLをハードコードしている場合- 絶対URLを使用しているテーマファイルおよびページビルダーのコンテンツ
修正1:設定画面でWordPressおよびホームURLを更新する
まずここから確認してください。最もよくある原因です。WordPress管理画面 → 設定 → 一般に移動し、両方のフィールドを変更します:
WordPress Address (URL): https://example.com
Site Address (URL): https://example.com
変更を保存をクリックします。WordPressからログアウトされるので、再ログインして南京錠が正常に表示されているか確認してください。
リダイレクトループでロックアウトされた場合は、代わりにwp-config.phpに直接URLを設定します:
define('WP_HOME', 'https://example.com');
define('WP_SITEURL', 'https://example.com');
修正2:データベース内のすべてのhttp:// URLを置換する(WP-CLI — 推奨)
設定画面での修正は2行しか更新しません。1年分のコンテンツがあるサイトでは、投稿・ウィジェット・オプション値にわたって500〜2,000件のハードコードされたhttp://リンクが存在することもあります。WP-CLIのsearch-replaceを使えば、一度にすべて処理できます:
# まずドライランで確認 — 何も変更せず変更対象を表示
wp search-replace 'http://example.com' 'https://example.com' --dry-run
# 実際に置換を実行
wp search-replace 'http://example.com' 'https://example.com' \
--skip-columns=guid \
--report-changed-only
# サイトがサブディレクトリにある場合はそのパスも置換
wp search-replace 'http://example.com/blog' 'https://example.com/blog' \
--skip-columns=guid
--skip-columns=guidフラグは投稿のGUIDを保持します。GUIDを変更すると、GUIDで投稿を識別するRSSリーダーが古い記事を新しい記事として再表示してしまいます。
search-replace実行後はキャッシュをフラッシュしてください:
wp cache flush
wp rewrite flush
修正3:Really Simple SSLプラグインを使用する(サーバーアクセス不要)
SSHアクセスがない場合は、WordPressプラグインディレクトリからReally Simple SSLプラグインをインストールしてください。有効化すると、以下の処理が行われます:
- WordPressおよびホームURLを自動的に更新
- HTTPからHTTPSへの301リダイレクトを追加
- 出力バッファリングを使用してURLを動的に書き換え、混在コンテンツを修正
設定 → SSLに移動し、**Go ahead, activate SSL!**をクリックしてください。
動作はしますが、出力バッファリングによりページレンダリングごとに約10〜30msのオーバーヘッドが発生します。データベースのURLを手動でクリーンアップした後は、プラグインを無効化してください。動的な書き換えは不要なオーバーヘッドになります。
修正4:.htaccessでHTTPSリダイレクトを強制する(Apache)
データベースのURLを正しく修正しても、ユーザーがアドレスバーに直接http://と入力した場合には対処できません。サーバーレベルのリダイレクトを追加してください。WordPressブロックより前に、.htaccessの先頭に以下を追加します:
# Force HTTPS
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
# BEGIN WordPress
# ... existing WordPress rules below ...
Nginxの場合は、サーバーブロックに以下を追加してください:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
修正5:残っている混在コンテンツのソースを特定する
データベースをクリーンにしても、テーマのPHPファイルやプラグインコードに直接ハードコードされたURLが残っている場合があります。ブラウザのDevToolsを使えば素早く見つけられます:
- Chrome DevToolsを開き → Consoleタブを選択
- **Mixed Content:**で始まる行を探す — 末尾のURLがHTTPで読み込まれているファイルを正確に示しています
- Networkタブに切り替え、httpでフィルタリングして安全でないリクエストをすべて確認
ファイルが特定できたら、テーマまたはプラグインのソースを検索します:
# 有効テーマ内のハードコードされたhttp://を検索
grep -r 'http://' /var/www/html/wp-content/themes/your-theme/ --include='*.php'
# 子テーマも確認
grep -r 'http://' /var/www/html/wp-content/themes/your-child-theme/ --include='*.php'
ハードコードされたhttp://example.comは、https://example.comまたは/wp-content/themes/...のような相対URLに置き換えてください。
修正が完了したか確認する
完了を確認するための3つの簡単なチェック:
- ブラウザの南京錠:鍵アイコンが警告の三角マークなしで表示されていること。クリックして「接続は保護されています」と表示されるか確認。
- コンソールチェック:DevTools → Consoleを開く。「Mixed Content:」で始まる行がゼロであれば正常です。
- オンラインチェッカー:URLをwhynopadlock.comまたはSSL Labsで確認 — すべてのページリソースをスキャンし、残っているHTTPアセットを検出します。
# WP-CLIでデータベースのURLが正しく更新されているか確認
wp option get siteurl
wp option get home
# どちらもhttps://example.comを返すはずです
予防策
最もクリーンなアプローチは、最初の投稿を公開する前にSSLをインストールすることです。移行作業も、search-replaceも、クリーンアップも不要になります。
既存サイトを移行する場合は、新しいコンテンツが追加される前に、DNSをHTTPSに切り替えた直後にWP-CLIのsearch-replaceを実行してください。
永続的なセーフティネットとして、wp-config.phpに以下を追加してください:
define('FORCE_SSL_ADMIN', true);
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}
2番目のブロックはリバースプロキシへの対応です。Cloudflare、ロードバランサー、ほとんどのマネージドホスティングはSSLをネットワークエッジで終端します。プロキシと実際のサーバー間のトラフィックは平文のHTTPで通信されます。このコードがなければ、WordPressはその内部HTTP接続を検知し、リクエストを誤って安全でないものとして扱い、管理画面のリダイレクトやログインフローが壊れてしまいます。

