些細なpostMessage
サンプルを機能させようとしています...
これらの条件のいずれかを削除すると、問題なく動作します:-)
しかし、私が知る限り、inter-window postMessage
は、両方のウィンドウがOriginを共有している場合にのみIE10で機能するように見えます。 (まあ、実際、奇妙なことに、動作はそれよりも少し寛容です:Hostを共有する2つの異なる起源も機能するようです)。
(注: この質問 問題に触れますが、 その答え はIE8とIE9についてです-10ではありません)
詳細+例...
<!DOCTYPE html>
<html>
<script>
window.addEventListener("message", function(e){
console.log("Received message: ", e);
}, false);
</script>
<button onclick="window.open('http://jsbin.com/ameguj/1');">
Open new window
</button>
</html>
<!DOCTYPE html>
<html>
<script>
window.opener.postMessage("Ahoy!", "*");
</script>
</html>
http://jsbin.com/ahuzir/1 -両方のページが同じOrigin(jsbin.com)でホストされているためです。しかし、2番目のページを他の場所に移動すると、IE10で失敗します。
私がこの回答を最初に投稿したとき、私は間違っていました:IE10では実際には動作しません。どうやらこれは他の理由で有用であることがわかっているので、後世のために残しています。以下の元の回答:
注目に値する:あなたがリンクした回答のリンクは、postMessage
がIE8とIE9の別々のウィンドウのOriginを超えていないことを示しています-しかし、IE10が登場する前の2009年にも書かれました。ですから、IE10で修正されたことを示すものとしてそれを受け取らないでしょう。
postMessage
自体については、 http://caniuse.com/#feat=x-doc-messaging は、IE10でまだ壊れていることを示しており、デモと一致しているようです。 caniuseページは この記事 にリンクしており、非常に関連性の高い引用が含まれています。
Internet Explorer 8以降では、ドキュメント間のメッセージングが部分的にサポートされています。現在はiframeで動作しますが、新しいウィンドウでは動作しません。ただし、Internet Explorer 10はMessageChannelをサポートします。 Firefoxは現在、クロスドキュメントメッセージングをサポートしていますが、MessageChannelはサポートしていません。
したがって、おそらく最善の策はMessageChannel
ベースのコードパスを用意し、それが存在しない場合はpostMessage
にフォールバックすることです。 IE8/IE9のサポートは受けられませんが、少なくともIE10では動作します。
MessageChannel
のドキュメント: http://msdn.Microsoft.com/en-us/library/windows/apps/hh441303.aspx
ランチャーと同じホストにプロキシページを作成します。プロキシページには、ソースがリモートページに設定されたiframe
があります。 Cross-Origin postMessageはIE10で次のように機能するようになりました。
window.parent.postMessage
を使用してデータをプロキシページに渡します。これはiframeを使用するため、IE10でサポートされていますwindow.opener.postMessage
を使用してデータをランチャーページに返します。これは同じドメイン上にあるため、クロスオリジンの問題はありません。 postMessageを使用したくない場合は、ランチャーページでグローバルメソッドを直接呼び出すこともできます。 window.opener.someMethod(data)
http://example.com/launcher.htm
のランチャーページ
<!DOCTYPE html>
<html>
<head>
<title>Test launcher page</title>
<link rel="stylesheet" href="/css/style.css" />
</head>
<body>
<script>
function log(msg) {
if (!msg) return;
var logger = document.getElementById('logger');
logger.value += msg + '\r\n';
}
function toJson(obj) {
return JSON.stringify(obj, null, 2);
}
function openProxy() {
var url = 'proxy.htm';
window.open(url, 'wdwProxy', 'location=no');
log('Open proxy: ' + url);
}
window.addEventListener('message', function(e) {
log('Received message: ' + toJson(e.data));
}, false);
</script>
<button onclick="openProxy();">Open remote</button> <br/>
<textarea cols="150" rows="20" id="logger"></textarea>
</body>
</html>
http://example.com/proxy.htm
のプロキシページ
<!DOCTYPE html>
<html>
<head>
<title>Proxy page</title>
<link rel="stylesheet" href="/css/style.css" />
</head>
<body>
<script>
function toJson(obj) {
return JSON.stringify(obj, null, 2);
}
window.addEventListener('message', function(e) {
console.log('Received message: ' + toJson(e.data));
window.opener.postMessage(e.data, '*');
window.close(self);
}, false);
</script>
<iframe src="http://example.net/remote.htm" frameborder="0" height="300" width="500" marginheight="0" marginwidth="0" scrolling="auto"></iframe>
</body>
</html>
http://example.net/remote.htm
のリモートページ
<!DOCTYPE html>
<html>
<head>
<title>Remote page</title>
<link rel="stylesheet" href="/css/style.css" />
</head>
<body>
<script>
function remoteSubmit() {
var data = {
message: document.getElementById('msg').value
};
window.parent.postMessage(data, '*');
}
</script>
<h2>Remote page</h2>
<input type="text" id="msg" placeholder="Type a message" /><button onclick="remoteSubmit();">Close</button>
</body>
</html>
もつれによる答えに基づいて、私は次のスニペットを使用してIE11 [およびエミュレートされたIE10モード]で成功しました:
var submitWindow = window.open("/", "processingWindow");
submitWindow.location.href = 'about:blank';
submitWindow.location.href = 'remotePage to comunicate with';
それから、典型的なpostMessageスタックを使用して通信できました。シナリオでは1つのグローバルな静的メッセンジャーを使用しています(重要性はないと思いますが、メッセンジャークラスも添付します)
var messagingProvider = {
_initialized: false,
_currentHandler: null,
_init: function () {
var self = this;
this._initialized = true;
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
eventer(messageEvent, function (e) {
var callback = self._currentHandler;
if (callback != null) {
var key = e.message ? "message" : "data";
var data = e[key];
callback(data);
}
}, false);
},
post: function (target, message) {
target.postMessage(message, '*');
},
setListener: function (callback) {
if (!this._initialized) {
this._init();
}
this._currentHandler = callback;
}
}
どんなに努力しても、IE9とIE8で物事を機能させることはできませんでした
それが機能している私の設定:
IEバージョン:11.0.10240.16590、アップデートバージョン:11.0.25(KB3100773)
LyphTECとAkrikosの回答に基づいて、別の回避策は、空白のポップアップウィンドウ内に<iframe>
を作成することです。空白のポップアップはオープナーと同じOriginを持っているので、別のプロキシページは必要ありません。
http://example.com/launcher.htm
のランチャーページ
<html>
<head>
<title>postMessage launcher</title>
<script>
function openWnd() {
var w = window.open("", "theWnd", "resizeable,status,width=400,height=300"),
i = w.document.createElement("iframe");
i.src = "http://example.net/remote.htm";
w.document.body.appendChild(i);
w.addEventListener("message", function (e) {
console.log("message from " + e.Origin + ": " + e.data);
// Send a message back to the source
e.source.postMessage("reply", e.Origin);
});
}
</script>
</head>
<body>
<h2>postMessage launcher</h2>
<p><a href="javascript:openWnd();">click me</a></p>
</body>
</html>
http://example.net/remote.htm
のリモートページ
<html>
<head>
<title>postMessage remote</title>
<script>
window.addEventListener("message", function (e) {
alert("message from " + e.Origin + ": " + e.data);
});
// Send a message to the parent window every 5 seconds
setInterval(function () {
window.parent.postMessage("hello", "*");
}, 5000);
</script>
</head>
<body>
<h2>postMessage remote</h2>
</body>
</html>
これがどれほど脆弱かはわかりませんが、IE 11およびFirefox 40.0.3で動作しています。
現在(2014-09-02)、最善の策は、この問題の回避策を詳しく説明したmsdnブログ投稿に記載されているプロキシフレームを使用することです。 https://blogs.msdn.Microsoft.com/ieinternals/2009/09/15/html5-implementation-issues-in-ie8-and-later /
以下に作業例を示します。 http://www.debugtheweb.com/test/xdm/Origin/
ポップアップと同じOriginを持つプロキシフレームをページに設定する必要があります。 window.opener.frames[0]
を使用して、ポップアップからプロキシフレームに情報を送信します。次に、プロキシフレームからメインページへのpostMessageを使用します。
このソリューションでは、サイトをInternet Exploreの信頼済みサイトに追加し、ローカルイントラネットサイトに not を追加します。このソリューションは、Windows 10/IE 11.0.10240.16384、Windows 10/Microsoft Edge 20.10240.16384.0、およびWindows 7 SP1/IE 10.0.9200.17148でテストしました。 ページをイントラネットゾーンに含めないでください。
Internet Explorerの構成([ツール]> [インターネットオプション]> [セキュリティ]> [信頼済みサイト]> [サイト])を開き、ページを追加します。ここでは、*を使用してすべてのサブドメインを一致させます。 ローカルイントラネットサイトにリストされているページis n'tを確認します([ツール]> [インターネットオプション]> [セキュリティ]> [ローカルイントラネット]> [サイト]> [詳細])。もう一度テストします。
Windows 10/Microsoft Edgeでは、この設定は[コントロールパネル]> [インターネットオプション]にあります。
UPDATE
これが機能しない場合は、ツール>インターネットオプション>詳細設定> Internet Explorerの設定をリセットですべての設定をリセットしてから、リセットしてみてください:注意!その後、システムを再起動する必要があります。その後、信頼済みサイトにサイトを追加します。
[ファイル]> [プロパティ]または右クリックを使用して、ページがどのゾーンにあるかを確認します。
UPDATE
私は企業のイントラネットにいますが、時には機能しますが、時には機能しません(自動構成?企業のプロキシを非難し始めました)。最終的に私はこのソリューションを使用しました https://stackoverflow.com/a/36630058/2692914 。