Mixed Content(混在コンテンツ)はHTTPSサイトから配信されるデータの中にHTTPで送られるコンテンツが含まれている時に発生します。
Mixed Contentが存在すると暗号化されていないコンテンツに悪意のある第三者がアクセスできてしまい、セキュアではなくなります。
せっかくSSL化したページなのに「安全ではありません」という表記になってしまいます。


さらに、Googleでは今後リリースされるGoogle ChromeではこのMixed Contentをブロックするという発表がありました。(2019年10月)
Chrome 79 から始まる一連のステップで、Chrome はデフォルトですべての混合コンテンツをブロックするように徐々に移行します。
No More Mixed Messages About HTTPS Googleセキュリティブログ
FirefoxでもFirefox 23より混合コンテンツをブロックするようになっています。
この記事ではMixed Content(混在コンテンツ)が発生する原因とエラーを解消する方法と、正常にSSL化されているかをチェックするツールを紹介します。
Mixed Content(混在コンテンツ)が発生する原因は
文頭で述べたようにページコンテンツにhttpから始まるリソースが含まれているとMixed Content(混在コンテンツ)が発生してしまいます。
画像リンクのほか、JavaScript,CSSなどです。
受動的なMixed Content(混在コンテンツ)の例
<img> (src 属性)
<audio> (src 属性)
<video> (src 属性)
<object> サブリソース (<object> が HTTP リクエストを送信したとき)能動的なMixed Content(混在コンテンツ)の例
<script> (src 属性)
https://developer.mozilla.org/ja/docs/Web/Security/Mixed_content
<link> (href 属性) (CSS スタイルシートも含む)
<iframe> (src 属性)
XMLHttpRequest リクエスト
fetch() リクエスト
url 値を用いる CSS すべて (@font-face / cursor / background-image など)
<object> (data 属性)
Navigator.sendBeacon (url 属性)
MDNではMixed Contentには受動的・能動的の2種類があると説明されています。
受動的な混在コンテンツは危険性が低いのですが、能動的な混在コンテンツはフィッシングや盗聴、悪意のあるサイトへのリダイレクトなどの脅威が想定されるということです。
jQueryUIを読み込んだエラー例
jQueryUIのデイトピッカーの日本語化ファイル(jquery.ui.datepicker-ja.js)をWordPressで読み込んだ例です。
wp_enqueue_script('jquery.ui.datepicker-ja','http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/i18n/jquery.ui.datepicker-ja.js');
WordPressのenqueueスクリプトでhttpのURLを読み込んでいたためMixed Contentが発生しました。
Mixed Content:The page at '該当ページのURL' was loaded over HTTPS,
but requested an insecure script 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/i18n/jquery.ui.datepicker-ja.js'. This request has been blocked; the content must be served over HTTPS.
メッセージの内容は、該当ページはSSL化でロードされたのに、デイトピッカーの日本語化ファイルjquery.ui.datepicker-ja.jsを読み込んでいるURLはhttpsじゃないからブロックしてる。。。httpsで読み込みなさいといった感じで怒られます。
masonry.jsをhttpで読み込んだときのメッセージ
jQueryのmasonryをhttpで読み込んだときはデベロッパーツールではエラーが表示されるのですがアドレスバーの鍵アイコンは表示されます。

Mixed Content: The page at 'https://example.com/XXX/' was loaded over HTTPS, but requested an insecure script 'http://example.com/XXX/js/masonry.pkgd.min.js'. This request has been blocked; the content must be served over HTTPS.

Firefoxでも鍵アイコンが表示されますが、ページの一部が安全でないと表示されます

JavaScriptのMixed Contentエラーの場合、JavaScriptは実行されません。
Mixed Content(混在コンテンツ)を確認するには
最新バージョンのGoogle ChromeやFirefoxでは、デベロッパーツールに警告やエラーが表示されるので原因を見つけやすくエラーを解消するのは比較的簡単です。
画像リンクにhttpリクエストが含まれている場合は以下のようなメッセージが表示されます。該当の画像を指定してくれているので修正しやすいです。
Google Chrome

Mixed Content: The page at 'https://example.com/XXX/' was loaded over HTTPS, but requested an insecure image 'http://example.com/XXX/images/thumb30.jpg'. This content should also be served over HTTPS.
コンソールのメッセージは「https://example.comt/XXX/はhttpsでロードされているけど、thumb30.jpgという画像はセキュアなリクエストじゃない」といった内容でしょうか。
JavaScriptの時よりはちょっと弱めの警告です。
Firefox
アドレスバーで鍵アイコンをクリックするとページ情報を表示できます。

さらに右矢印をクリックすると「このサイトとの接続は安全ではありません」と表示されます。
「詳細を表示」をクリックします。

メディアの項目ではリンクされている画像の一覧が見れます。ここでhttpになっている画像を確認することができます。

Mixed Content(混在コンテンツ)エラーを発生させないためには?
Mixed Content(混在コンテンツ)エラーにしないためには
画像やJavaScript,CSSなど外部ファイルは相対パスでリンクする
というのが一番安全です。
でもWordPressなどのCMSだとリンクは基本全て絶対パスになります。
wp_enqueueでCSSやJavaScriptを読み込む時に注意
wp_enqueue_styleやwp_enqueue_scriptでCSSやJavaScriptを読み込む時、get_stylesheet_uri()やget_template_directory_uri()関数を使って正しいパスを読み込むようにします。
function theme_name_scripts() {
wp_enqueue_style( 'style-name', get_stylesheet_uri() );
wp_enqueue_script( 'script-name', get_template_directory_uri() . '/js/example.js', array(), '1.0.0', true );
}
add_action( 'wp_enqueue_scripts', 'theme_name_scripts' );
また、CDN経由で外部ファイルを読み込む場合などはhttpになっていないか注意する必要があります。
httpsでリクエストされているはずがhttpが含まれていたりするとMixed Contentエラーが発生してしまいます。
wp_enqueue_script('jquery.ui.datepicker-ja','https://ajax.googleapis.com/ajax/libs/jqueryui/1/i18n/jquery.ui.datepicker-ja.min.js',array('jquery'),'', true);
Mixed Contentをチェックするツール
オンラインツールを使って、サイトをクロールして安全ではないコンテンツをチェックすることができます。
JitBit SSL Check

https://www.jitbit.com/sslcheck/
HTTPSのWebサイトをクロールしてブラウザーで「mixed content」の警告メッセージを出している画像、スクリプト、css ファイルを検索します。
サイトのURLを入力して送信するとサイトをチェックします。検索は400ページが上限になっています。

サイトをチェックした結果、「SSL Issues」以下にSSLでないコンテンツが発見されると赤い文字で表示されます。
URLをクリックしてみるとSSL対応していない画像を表示してくれます。

Missing Padlock SSL Checker

https://www.missingpadlock.com/
Missing Padlockはサイトをクロールして画像, 音声, 動画, frames, CSS, JavaScript, フォームを探してチェックします。
既にhttpsのページをクロールして安全でないコンテンツを検出します。
まだSSL対応していないページ(httpから始まるURL)の場合はSSL対応した場合にMixed Contentを引き起こすページを検出してくれます。

まとめ
Mixed Contentとは何か?発生したときの状態や解消する方法について解説しました。
Mixed Contentが存在するとブラウザでブロックされてしまうのでコンテンツが正常に動作しない場合があります。
また何よりフィッシングや悪意のあるサイトへのリダイレクトされるなど脅威が想定されるため発見したら直ちに修正することが推奨されます。
Mixed Contentをチェックするオンラインツールも紹介していますので定期的にサイトをチェックするといいですね。