HTTPSのページからHTTPのリソースをXHRで取得する方法
出来ないかと思いましたが、Firefox 55.0.3で出来る方法がありました。
下記のサンプルはhttps://example.comで実行するとHello Worldと出ます。
(function (i) { var w = i.contentWindow; onmessage = function (e) { if (e.source === w) alert(e.data); }; i.sandbox = 'allow-scripts'; i.src = 'data:text/html,%3Cscript%3Evar%20a%20%3D%20new%20XMLHttpRequest%3Ba.onload%3Dfunction()%7Bparent.postMessage(a.responseText%2C%22https%3A%2F%2Fexample.com%22)%7D%3Ba.open(%22get%22%2C%22http%3A%2F%2F1mu.info%2Fjunk%2Fhello.txt%22)%3Ba.send()%3C%2Fscript%3E'; })(document.body.appendChild(document.createElement('iframe')));
尚、Data URIの内容は下記のようになっています。
<script> var a = new XMLHttpRequest; a.onload = function () { parent.postMessage(a.responseText, "https://example.com"); }; a.open("get", "http://1mu.info/junk/hello.txt"); a.send(); </script>
Chromeだと混在コンテンツとしてエラーが出ます。この方法はFirefoxでも近いうちに使えなくなるかもしれません。
別の手段としてiframeではなくpostMessage用ページを開く方法を考えました。
この方法はChrome 60.0.3112.113とFirefox 55.0.3で動作しました。今後使えなくなるかどうかはわかりませんが、ユーザーのクリックを待つのと新規タブを開いておく必要があるのであまりいい方法ではないと思います。
下記のサンプルはhttps://example.comで実行したあとページのどこかをクリックするとHello Worldと出ます。
document.addEventListener('click', function () { var w = open('http://1mu.info/junk/postmessage.html'); onmessage = function (e) { if (e.origin === 'http://1mu.info' && e.source === w) alert(e.data) }; });