2026年7月24日

2026年7月24日

WordPressの混在コンテンツ(Mixed Content)エラーを解決する方法

はじめに

サイトをHTTPS化した後にブラウザのアドレスバーに鍵マークが表示されない、コンソールに「Mixed Content」エラーが出る場合、ページ内にHTTPのリソース(画像・CSS・JS)が残っています。WP-CLIのsearch-replaceとCSP設定で解消できます。

症状・原因

  • アドレスバーに「保護されていません」または鍵に斜線が表示される
  • ブラウザのコンソールに「Mixed Content: The page was loaded over HTTPS...」が表示される
  • HTTPS化後も一部の画像・埋め込みコンテンツがHTTPのURLを参照している
  • テーマ・プラグインがハードコードしたHTTP URLを使っている

解決手順

ステップ1:Mixed Content の原因を特定する

# ブラウザの開発者ツール(F12)でコンソールを確認
# 「Mixed Content」メッセージのURLをメモする

# WP-CLI で DB 内の http:// URL を検索
wp search-replace 'http://example.com' 'https://example.com' \
    --dry-run --all-tables --skip-columns=guid \
    --report-changed-only

# http:// を含む投稿・オプションを調べる
wp db query "SELECT ID, post_title FROM wp_posts
WHERE post_content LIKE '%src=\"http://%'
   OR post_content LIKE '%href=\"http://%'
LIMIT 20;"

ステップ2:WP-CLI で DB 内の URL を一括置換する

# ① ドライランで影響範囲を確認
wp search-replace 'http://example.com' 'https://example.com' \
    --dry-run --all-tables --skip-columns=guid

# ② 本番実行
wp search-replace 'http://example.com' 'https://example.com' \
    --all-tables --skip-columns=guid

# ③ シリアライズデータも自動変換される(WordPress の場合デフォルト)
# --no-regex オプションなしで実行すること

# ④ パーマリンクを再構築
wp rewrite flush --hard

# ⑤ キャッシュをクリア
wp cache flush
wp transient delete --all

ステップ3:テーマ・プラグインのハードコード URL を修正する

// functions.php: コンテンツ内の http:// を動的に https:// に変換
add_filter('the_content', 'fix_mixed_content_in_content');
add_filter('widget_text', 'fix_mixed_content_in_content');

function fix_mixed_content_in_content(string $content): string {
    if (is_ssl()) {
        $content = str_replace(
            'http://' . $_SERVER['HTTP_HOST'],
            'https://' . $_SERVER['HTTP_HOST'],
            $content
        );
    }
    return $content;
}

// スクリプト・スタイルの src を強制 https に変換
add_filter('script_loader_src', 'fix_mixed_content_url');
add_filter('style_loader_src', 'fix_mixed_content_url');

function fix_mixed_content_url(string $src): string {
    if (strpos($src, 'http://') === 0 && is_ssl()) {
        $src = str_replace('http://', 'https://', $src);
    }
    return $src;
}

ステップ4:.htaccess で CSP ヘッダーを設定する

# .htaccess: Content-Security-Policy で Mixed Content をブロック・アップグレード
<IfModule mod_headers.c>
    # http を自動的に https にアップグレード(モダンブラウザ)
    Header always set Content-Security-Policy "upgrade-insecure-requests"

    # 厳格なCSP(自サイトのリソースのみ許可する場合)
    # Header always set Content-Security-Policy "default-src 'self' https:; img-src 'self' https: data:; script-src 'self' https: 'unsafe-inline'; style-src 'self' https: 'unsafe-inline'"
</IfModule>
// wp-config.php または functions.php でヘッダーを追加
add_action('send_headers', function(): void {
    header('Content-Security-Policy: upgrade-insecure-requests');
});

ステップ5:メディアライブラリの URL を更新する

# メディアの添付ファイル URL を確認
wp db query "SELECT ID, guid FROM wp_posts
WHERE post_type = 'attachment'
  AND guid LIKE 'http://%'
LIMIT 20;"

# 添付ファイルの guid を更新(guid は通常変えないが混在解消のため)
wp search-replace 'http://example.com/wp-content/uploads' \
    'https://example.com/wp-content/uploads' \
    wp_posts --skip-columns=''

# wp_postmeta の _wp_attached_file も更新(相対パスなので通常不要)
wp db query "SELECT meta_value FROM wp_postmeta
WHERE meta_key = '_wp_attachment_metadata'
  AND meta_value LIKE '%http://%'
LIMIT 5;"

注意事項

  • wp search-replaceは必ず--dry-runで影響範囲を確認してから本番実行してください。シリアライズされたPHPデータも自動的に処理されますが、件数が多い場合はメモリ不足になる場合があります
  • upgrade-insecure-requests CSPディレクティブはブラウザがHTTPリソースをHTTPSに自動変換しますが、HTTPSが存在しないリソースはブロックされます。根本的な解決にはDB内URLの置換が必要です
  • サードパーティの埋め込み(YouTube・Google Maps等)がHTTPを使っている場合はCSPで許可するか、HTTPS対応の埋め込みURLに手動変更してください

まとめ

Mixed Content解消は①ブラウザコンソールとwp search-replace --dry-runで混在URLを特定、②wp search-replace 'http://example.com' 'https://example.com' --all-tables --skip-columns=guidで一括置換、③script_loader_src/style_loader_srcフィルターでプラグインのハードコードURLを動的変換、④.htaccessContent-Security-Policy: upgrade-insecure-requestsを設定、⑤メディアライブラリのguidとattachment URLも合わせて置換します。

お気軽にご相談ください

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