MeWrite Docs

Mixed Content

HTTPSページからHTTPリソースを読み込もうとした際のエラー

概要

Mixed Content(混在コンテンツ)エラーは、HTTPSで配信されるページがHTTP(非暗号化)のリソース(画像、スクリプト、スタイルシート等)を読み込もうとした場合に発生します。

エラーメッセージ

Mixed Content: The page at 'https://example.com/' was loaded over HTTPS,
but requested an insecure resource 'http://example.com/image.jpg'.
This request has been blocked; the content must be served over HTTPS.

または

混在コンテンツ: 'https://example.com/' のページが HTTPS で読み込まれましたが、
安全でないリソース 'http://example.com/image.jpg' をリクエストしました。
このリクエストはブロックされました。

原因

  1. ハードコードされたHTTP URL: コード内にhttp://が残っている
  2. 外部リソース: HTTPのみ対応のCDNや外部サービス
  3. データベース内のURL: CMSに保存された古いURL
  4. 相対プロトコル未使用: プロトコルを明示的に指定

Mixed Contentの種類

Passive/Display Mixed Content(表示型)

- 画像 (<img>)
- 動画 (<video>)
- 音声 (<audio>)

警告は出るが、多くのブラウザでは読み込まれる

Active Mixed Content(アクティブ型)

- JavaScript (<script>)
- CSS (<link rel="stylesheet">)
- iframe (<iframe>)
- XMLHttpRequest / Fetch
- WebSocket

セキュリティリスクが高いため、ブロックされる

解決策

1. 相対プロトコルまたはHTTPSを使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<!-- 問題のあるコード -->
<img src="http://example.com/image.jpg">
<script src="http://cdn.example.com/lib.js"></script>

<!-- 修正版: HTTPS を使用 -->
<img src="https://example.com/image.jpg">
<script src="https://cdn.example.com/lib.js"></script>

<!-- 修正版: プロトコル相対URL(非推奨だが動作する) -->
<img src="//example.com/image.jpg">

2. Content-Security-Policy で自動アップグレード

1
2
<!-- HTML meta タグ -->
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
1
2
# Nginx
add_header Content-Security-Policy "upgrade-insecure-requests" always;
1
2
# Apache
Header always set Content-Security-Policy "upgrade-insecure-requests"

3. データベース内URLの一括置換

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
-- WordPress の例
UPDATE wp_posts
SET post_content = REPLACE(post_content, 'http://example.com', 'https://example.com');

UPDATE wp_postmeta
SET meta_value = REPLACE(meta_value, 'http://example.com', 'https://example.com');

UPDATE wp_options
SET option_value = REPLACE(option_value, 'http://example.com', 'https://example.com')
WHERE option_name = 'home' OR option_name = 'siteurl';

4. JavaScript での検出と修正

1
2
3
4
5
6
7
8
// 動的にHTTPS化
document.querySelectorAll('img[src^="http://"]').forEach(img => {
  img.src = img.src.replace('http://', 'https://');
});

// Fetch/XHR でHTTPS強制
const secureUrl = url => url.replace(/^http:\/\//i, 'https://');
fetch(secureUrl(apiUrl));

5. 開発時のMixed Content確認

1
2
3
4
5
6
7
// Service Worker で検出
self.addEventListener('fetch', event => {
  const url = new URL(event.request.url);
  if (url.protocol === 'http:' && url.hostname !== 'localhost') {
    console.warn('Mixed content detected:', url.href);
  }
});
1
2
# ページ内のHTTPリソースを検索
curl -s https://example.com | grep -oE 'http://[^"'"'"'> ]+'

6. CSPレポートで監視

1
2
3
# Nginx - レポートのみ(ブロックしない)
add_header Content-Security-Policy-Report-Only
  "default-src https:; report-uri /csp-report" always;
1
2
3
4
5
// レポート受信エンドポイント
app.post('/csp-report', express.json({ type: 'application/csp-report' }), (req, res) => {
  console.log('CSP Violation:', req.body);
  res.status(204).end();
});

ブラウザでの確認方法

Chrome DevTools:
1. F12 で開発者ツールを開く
2. Console タブで警告/エラーを確認
3. Network タブで "mixed-content" をフィルタ
4. Security タブで詳細を確認

Browser の他のエラー

最終更新: 2026-01-27