マガジン

「Mixed Content」エラーでゲームの素材が読めないとき

遊びをつくる

執筆にClaudeを使用しています。

不具合の起きた順番を絵札で並べ、相手に伝えるための手紙を整える手元。
記事のテーマをもとに制作したAI生成イラスト。

ゲームをHTTPSのサイトに公開した直後、画像が表示されない、BGMが鳴らない、JSONファイルが読み込めない——そんな状況でブラウザの開発者ツールを開くと、「Mixed Content」という赤いエラーが並んでいることがあります。コードは正しいのに素材だけ消える、という症状の多くはこのエラーが原因です。 Mixed Contentとは、HTTPSで配信されているページの中から、HTTPで配信されている素材を読もうとしたときにブラウザが発生させるエラーです。ブラウザはHTTPSページの安全性を守るため、暗号化されていないHTTPの通信を遮断します。結果として素材のURLだけが古いままのゲームは、ローカルでは動くのに公開すると壊れる、という状態になります。 この記事では、Mixed Contentエラーの種類と見分け方、素材ごとの対処方針、よくある落とし穴の順で説明します。読み終わったあとに、自分のゲームのどこを直せばいいか判断できることを目標にしています。

この記事の目次
  1. エラーの種類と深刻度の違い
  2. 原因を特定する手順
  3. 素材の種類ごとの対処方針
  4. プロトコル相対URLという選択肢とその注意点
  5. 修正後の確認と再発防止
  6. 次の行動
  7. 参考資料

エラーの種類と深刻度の違い

Mixed Contentには「Blocked(遮断)」と「Warning(警告)」の二段階があります。

Blockedになるものは、スクリプト・スタイルシート・フォント・XHR/Fetch通信・WebSocket、そして<iframe>で埋め込んだコンテンツです。これらはブラウザがリクエスト自体をキャンセルするため、素材は一切届きません。ゲームエンジンがHTTPのAPIエンドポイントへFetchしているケース、外部CDNのJavaScriptライブラリをHTTP URLで読み込んでいるケースが典型です。

Warningになる(またはかつてなっていた)ものは画像・音声・動画です。仕様上は「Optionally Blockable」と呼ばれ、以前は警告のみで表示されることもありましたが、Chromeをはじめとする主要ブラウザは段階的に画像・音声・動画もBlockedに移行しています。現時点では「画像はまだ通る」と期待しないほうが安全です。公開環境で確認するブラウザと版数によって挙動が変わることがあるため、常に開発者ツールのConsoleタブとNetworkタブの両方を確認してください。

開発者ツールでエラーを確認するときは、Consoleタブに「Mixed Content: The page at 'https://…' was loaded over HTTPS, but requested an insecure resource 'http://…'」のような文言が出ます。その右側にあるファイル名と行番号が修正の手がかりになります。

原因を特定する手順

  1. ブラウザの開発者ツールを開く(Windows: F12 / Mac: Cmd+Option+I)
  2. ConsoleタブでMixed Contentの行を探し、問題のURLをメモする
  3. Networkタブでページを再読み込みし、Statusが「(blocked:mixed-content)」になっているリクエストをすべて拾う
  4. メモしたURLが自分のコードのどこに書かれているかを検索する

HTML・JavaScript・CSS・JSONの中にハードコードされたhttp://から始まるURLが一箇所でも残っていれば、それが原因です。複数のファイルに分散していることも多いため、テキストエディタの「フォルダ全体を対象にした文字列検索」でhttp://を一括検索すると見落としを防げます。

外部ライブラリを使っている場合は、ライブラリ自体が内部でHTTPの素材を読み込んでいることもあります。その場合は行番号がライブラリのコードを指すので、使っているライブラリの最新版に差し替えるか、自分でホストし直すかを検討します。

素材の種類ごとの対処方針

自分でホストしている素材

もっとも簡単な修正は、URLのスキームをhttp://からhttps://に書き換えることです。素材のサーバー側がHTTPSに対応していれば、URLを変えるだけで解決します。サーバーがHTTPにしか対応していない場合は、素材をHTTPS対応のホスティング先に移す必要があります。

外部CDNから読み込んでいるライブラリや素材

外部CDNのURLがhttp://のままになっているケースは、ライブラリを導入した時期が古いと起きやすいです。CDNのサービス側はほぼHTTPSに対応しているため、URLをhttps://に変えるだけで済むことがほとんどです。ただし、URLが変わっていたり古いバージョンがCDNから削除されていたりするケースもあるため、CDNの公式サイトで現行のURLを確認してから書き換えてください。

音声・動画ファイル

<audio src="http://…">や<video src="http://…">のような直書きに加えて、JavaScriptでnew Audio("http://…")と生成しているケースも見落としやすいです。HTMLとJSの両方を確認してください。

Fetch・XHRで取得するJSONやAPIレスポンス

ゲームの初期化時に外部のデータAPIをHTTPで叩いているケースは、Blockedになるとゲーム全体が起動しません。APIのエンドポイントがHTTPSに対応していない場合は、サーバー側の設定変更が必要です。自分で管理できないAPIであれば、自分のサーバーをプロキシとして挟む方法が一般的です。

`<iframe>`で埋め込んでいるコンテンツ

iframeのsrc属性がhttp://のURLを指していると、iframeごとBlockedになります。埋め込み先のサービスがHTTPSに対応しているURLを提供しているか確認し、srcを書き換えてください。対応していない場合は埋め込みを使わず、リンクに切り替えることを検討します。

プロトコル相対URLという選択肢とその注意点

//cdn.example.com/lib.jsのようにhttp:もhttps:も省いた書き方を「プロトコル相対URL」と呼びます。ページがHTTPSで配信されていればhttps:として、HTTPならhttp:として動作します。ローカルでfile://から開くとfile://cdn.example.com/…と解釈されて失敗するため、ローカル確認をブラウザで直接ファイルを開いて行っている人には向きません。ローカルサーバー(localhostなど)を立てて確認している場合は問題になりにくいです。

現代のウェブ開発では、素材を配信するサーバー自体がHTTPSに対応しているなら最初からhttps://を明示したほうが混乱が少ないです。プロトコル相対URLは「どちらの環境でも動く」というメリットがありますが、HTTPのサーバーに誘導される余地も残るため、セキュリティを重視する場面ではhttps://固定が無難です。

修正後の確認と再発防止

修正したらブラウザのキャッシュをクリアしてページを再読み込みし、開発者ツールのConsoleとNetworkタブにMixed ContentエラーとBlockedのリクエストがゼロになっていることを確認します。

再発を防ぐには、新しい素材を追加するたびに外部URLがhttps://であることをその場でチェックする習慣が最も確実です。複数人で開発している場合は、コードレビューの際にhttp://で始まる外部URLが混入していないかを確認する項目をチェックリストに加えておくと見落としを減らせます。

また、Content Security Policy(CSP)のヘッダーを設定してupgrade-insecure-requestsディレクティブを使うと、ブラウザ側がHTTPリクエストを自動的にHTTPSに格上げしようとします。ただしこれはあくまで補助的な手段で、素材のサーバーがHTTPSに対応していなければリクエスト自体が失敗します。根本的な修正の代替にはなりません。

次の行動

開発者ツールのNetworkタブで「(blocked:mixed-content)」のリクエストを洗い出し、該当するURLをコード内で検索してhttps://に書き換えてから再確認してください。アソバースにZIPまたはHTMLをアップロードして公開する場合も、公開後にブラウザで開いて同じ手順でエラーがないことを必ず確認しておくと安心です。

参考資料

  • MDN Web Docs「Mixed content」
  • Google Developers「Fixing mixed content」
  • Content Security Policy Level 3 仕様(W3C)