2026年7月24日

2026年7月24日

WordPressの混在コンテンツ(Mixed Content)を直す方法|原因の特定とURLの一括置換

サイトをHTTPSに切り替えたあと、ページの中に http:// で始まる画像・スクリプト・CSSなどが残っていると、「混在コンテンツ(Mixed Content)」になります。この記事では、どのURLが原因かを特定し、データベース、テーマ、サーバー設定のそれぞれで直す手順を説明します。

混在コンテンツで起きること

HTTPSのページから http:// のリソースを読み込もうとすると、ブラウザは次のように扱います(2026年10月時点の Chrome や Firefox などの主要ブラウザ)。

  • 画像・音声・動画: https:// に読み替えて読み込みを試みる。読み替えた先が存在しなければ表示されない
  • スクリプト・CSS・iframe など: 読み込みをブロックする。レイアウトが崩れたり、機能が動かなくなったりする

いずれの場合も、ブラウザの開発者ツールのコンソールに「Mixed Content」で始まるメッセージが表示されます。

原因になっているURLを特定する

ブラウザのコンソールで確認する

問題のページを開き、開発者ツール(Windowsでは F12)の「Console」タブを見ます。メッセージに、読み込もうとした http:// のURLが表示されます。どのページで起きているかによって原因が変わるので、トップページ、投稿ページ、固定ページなど種類の違うページを確認します。

ページのHTMLから http:// を抜き出す

複数のページをまとめて確認するときは、HTMLから http:// を含むURLを抜き出します。

curl -s https://example.com/ | grep -oE "(src|href)=[\"']http://[^\"']+" | sort -u

見つかったURLが自サイトのもの(http://example.com/...)か、外部のもの(http://外部ドメイン/...)かで、直し方が変わります。

サイトのURL設定を確認する

まず、WordPress自体のURLがHTTPSになっているかを確認します。

wp option get home
wp option get siteurl

管理画面では「設定」→「一般」の「WordPress アドレス (URL)」と「サイトアドレス (URL)」です。wp-config.php で WP_HOME や WP_SITEURL を定義している場合は、そちらが優先されるので、定義も確認します。

grep -n -E "WP_HOME|WP_SITEURL" wp-config.php

WordPress 5.7以降では、サイトがまだHTTPで、サーバーがHTTPSに対応していれば、「ツール」→「サイトヘルス」に、2つのURLをまとめてHTTPSに切り替えるボタンが表示されます。

WordPress 5.7以降の自動置換について

WordPress 5.7以降では、記事のある既存サイトのURLをHTTPSに切り替えると、https_migration_required というオプションが有効になります。この状態では、投稿本文・抜粋・ウィジェット・追加CSSに含まれる自サイトの http:// のURLを、表示する時点で https:// に置き換えます。データベースの中身は書き換わらないので、次の節の置換を済ませたら、この仕組みは不要になります。

データベース内のURLを一括置換する

投稿本文やウィジェット、テーマの設定に保存された http://example.com を、WP-CLIの wp search-replace で置換します。シリアライズされたデータ(PHPの配列などを文字列にしたもの)も、文字数を合わせて置換されます。

# 1. バックアップを取る
wp db export before-https.sql

# 2. ドライランで、どのテーブルのどの列が何件変わるかを確認
wp search-replace 'http://example.com' 'https://example.com' \
    --all-tables-with-prefix --skip-columns=guid \
    --dry-run --report-changed-only

# 3. 問題がなければ実行
wp search-replace 'http://example.com' 'https://example.com' \
    --all-tables-with-prefix --skip-columns=guid --report-changed-only

# 4. オブジェクトキャッシュを使っている場合は削除
wp cache flush

--all-tables-with-prefix は、wp-config.php の接頭辞(例: wp_)で始まるテーブルをすべて対象にします。プラグインが作った独自テーブルも含まれます。www ありとなしの両方のURLを使っていた場合は、それぞれ置換します。

ページビルダーなど、URLをJSON形式で http:\/\/example.com のようにエスケープして保存するプラグインもあります。ドライランで次の形も確認し、件数があれば同じように置換します。

wp search-replace 'http:\/\/example.com' 'https:\/\/example.com' \
    --all-tables-with-prefix --skip-columns=guid --dry-run --report-changed-only

置換が終わったら、前の節の自動置換を止めてもかまいません。

wp option delete https_migration_required

guid 列は変更しない

wp_posts テーブルの guid 列は、投稿を一意に識別するための値で、RSSリーダーなどが既読の判定に使います。WordPressの公式ドキュメントでも、サイトの移転時に変更しないよう案内されています。ページの表示には使われないので、--skip-columns=guid で置換対象から外します。

メディアのURLが http:// のまま残る場合

画像のURLは、添付ファイルのメタデータ _wp_attached_file に保存された相対パス(例: 2026/10/photo.jpg)と、アップロード先のURLを組み合わせて作られます。通常はサイトのURLをHTTPSにすれば一緒に変わりますが、アップロード先のURLを upload_url_path オプションで指定している場合は、そちらも確認します。

wp option get upload_url_path

値が http:// で始まっていれば、https:// に変えるか、特別な理由がなければ空にします。

テーマやプラグインに書かれたURLを直す

データベースを置換してもエラーが残る場合は、テーマやプラグインのファイルに http:// が直接書かれている可能性があります。

grep -rn --include='*.php' --include='*.css' --include='*.js' 'http://' wp-content/themes/your-theme/

自作テーマや子テーマであれば、ファイルを直接直します。自サイト内のURLは home_url() や get_stylesheet_directory_uri() などの関数で作ると、HTTPSに切り替えたときにも自動で追従します。外部のリソースは、提供元がHTTPSに対応しているかを確かめてから https:// に書き換えます。HTTPSで提供されていないものは、別の提供元に切り替えるか、削除します。

配布されているテーマやプラグインで、ファイルを直接直せない場合は、作者に報告したうえで、一時的に読み込みURLをフィルターで書き換えます。wp-content/mu-plugins/ に次のファイルを置きます(フォルダーがなければ作ります)。

<?php
/**
 * Plugin Name: Force HTTPS for enqueued assets
 */
add_filter( 'script_loader_src', 'mysite_force_https_src' );
add_filter( 'style_loader_src', 'mysite_force_https_src' );

function mysite_force_https_src( $src ) {
	if ( is_ssl() && is_string( $src ) && 0 === strpos( $src, 'http://' ) ) {
		$src = set_url_scheme( $src, 'https' );
	}
	return $src;
}

このフィルターが効くのは、wp_enqueue_script() と wp_enqueue_style() で読み込まれるファイルだけです。テンプレートに <script src="http://..."> と直接書かれているものは変わりません。

リバースプロキシやCDNの背後で動かしている場合

ロードバランサーやCDNでHTTPSを終端し、WordPressのサーバーにはHTTPで転送している構成では、WordPressが自分はHTTPで動いていると判断し、http:// のURLを出力することがあります。プロキシが X-Forwarded-Proto ヘッダーを付けて転送している場合は、WordPressの公式ドキュメントにあるとおり、wp-config.php の require_once ABSPATH . 'wp-settings.php'; より上に次の行を加えます。

if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && false !== strpos( $_SERVER['HTTP_X_FORWARDED_PROTO'], 'https' ) ) {
	$_SERVER['HTTPS'] = 'on';
}

このヘッダーは送信元が自由に付けられるので、WordPressのサーバーにプロキシを経由せず直接アクセスできる構成では使わないでください。

CSPの upgrade-insecure-requests を設定する

Content-Security-Policy(CSP)の upgrade-insecure-requests を指定すると、ブラウザはページ内の http:// のリソースをすべて https:// に読み替えてから読み込みます。残ったURLを直すまでのつなぎとして使えます。

Apache(mod_headers が有効な場合)の .htaccess:

<IfModule mod_headers.c>
    Header always set Content-Security-Policy "upgrade-insecure-requests"
</IfModule>

Nginx のサーバー設定:

add_header Content-Security-Policy "upgrade-insecure-requests" always;

サーバー設定を変えられない場合は、PHPでヘッダーを送ります。wp-config.php の時点ではまだ add_action() が読み込まれていないので、テーマの functions.php か、前の節と同じ mu-plugins のファイルに書きます。

<?php
add_action( 'send_headers', function () {
	header( 'Content-Security-Policy: upgrade-insecure-requests' );
} );

読み替えた先にHTTPS版が存在しないリソースは、読み込みに失敗します。また、すでに別のCSPを設定している場合は、ヘッダーが重複しないよう、既存のポリシーに upgrade-insecure-requests を加えます。CSPはあくまで補助で、根本の対処はURLそのものを https:// に直すことです。

直ったことを確認する

  • キャッシュ系プラグインやCDNのキャッシュを削除する
  • ブラウザのキャッシュを使わない再読み込み(Windowsでは Ctrl + Shift + R)をして、コンソールに「Mixed Content」が出ないか確認する
  • アドレスバーの表示で、接続が保護されていることを確認する
  • トップページだけでなく、投稿・固定ページ・アーカイブなど種類の違うページも確認する

まとめ

  • ブラウザのコンソールで、原因の http:// のURLを特定する
  • home と siteurl、wp-config.php の WP_HOME・WP_SITEURL がHTTPSになっているか確認する
  • データベースは wp search-replace を --dry-run で確認してから、--skip-columns=guid を付けて置換する。エスケープされた http:\/\/ の形も確認する
  • テーマやプラグインに書かれたURLはファイルを直し、直せないものは mu-plugins のフィルターで一時的に対処する
  • プロキシの背後では X-Forwarded-Proto を見て $_SERVER['HTTPS'] を設定する
  • upgrade-insecure-requests はつなぎの対策。add_action() を使うコードは wp-config.php には書かない

関連記事:

お気軽にご相談ください

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