Saya mencoba membuat postMessage
contoh yang sepele berhasil ...
- di IE10
- antara jendela / tab (vs. iframe)
- melintasi asal
Hapus salah satu dari kondisi ini, dan semuanya berfungsi dengan baik :-)
Tapi sejauh yang saya tahu, antara jendela postMessage
hanya tampak berfungsi di IE10 ketika kedua jendela berbagi asal. (Sebenarnya - dan anehnya - perilakunya sedikit lebih permisif dari itu: dua asal berbeda yang berbagi host tampaknya juga berfungsi).
Apakah ini bug yang terdokumentasi? Ada solusi atau saran lain?
(Catatan: Pertanyaan ini menyentuh masalah, tetapi jawabannya tentang IE8 dan IE9 - bukan 10)
Lebih detail + contoh ...
demo halaman peluncur
<!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>
meluncurkan demo halaman
<!DOCTYPE html>
<html>
<script>
window.opener.postMessage("Ahoy!", "*");
</script>
</html>
Ini berfungsi di: http://jsbin.com/ahuzir/1 - karena kedua laman dihosting pada asal yang sama (jsbin.com). Tapi pindahkan halaman kedua ke tempat lain, dan itu gagal di IE10.
html
cross-browser
compatibility
internet-explorer-10
postmessage
Omong kosong
sumber
sumber
window.parent.postMessage
di IE.Jawaban:
Saya salah ketika saya awalnya memposting jawaban ini: itu tidak benar-benar berfungsi di IE10. Rupanya orang telah menemukan ini berguna untuk alasan lain jadi saya meninggalkannya untuk anak cucu. Jawaban asli di bawah ini:
Perlu dicatat: tautan dalam jawaban itu yang Anda tautkan ke status yang
postMessage
bukan merupakan asal silang untuk jendela terpisah di IE8 dan IE9 - namun, itu juga ditulis pada tahun 2009, sebelum IE10 muncul. Jadi saya tidak akan menganggapnya sebagai indikasi bahwa itu diperbaiki di IE10.Sedangkan untuk
postMessage
dirinya sendiri, http://caniuse.com/#feat=x-doc-messaging menunjukkan bahwa itu masih rusak di IE10, yang tampaknya cocok dengan demo Anda. Halaman caniuse tertaut ke artikel ini , yang berisi kutipan yang sangat relevan:Jadi taruhan terbaik Anda mungkin memiliki
MessageChannel
alur kode berbasis, dan mundur kepostMessage
jika itu tidak ada. Ini tidak akan memberi Anda dukungan IE8 / IE9, tetapi setidaknya itu akan bekerja dengan IE10.Dokumen di
MessageChannel
: http://msdn.microsoft.com/en-us/library/windows/apps/hh441303.aspxsumber
MessageChannel
kode berbasis yang berfungsi? Anda masih perlu berfungsipostMessage
untuk mendapatkan port saluran ke jendela lain.postMessage
denganMessageChannel
API baru akan berfungsi di jendela dan asal baru. Pekerjaannya agak canggung, saya kira, tetapi pada dasarnya:postMessage('foo', '*')
buruk,postMessage('foo', [messageChannel.port2])
itu baik.Buat halaman proxy di host yang sama dengan peluncur. Halaman proxy memiliki
iframe
sumber dengan yang disetel ke halaman jarak jauh. PostMessage lintas asal sekarang akan berfungsi di IE10 seperti:window.parent.postMessage
untuk melewatkan data ke halaman proxy. Karena ini menggunakan iframe, ini didukung oleh IE10window.opener.postMessage
untuk meneruskan data kembali ke halaman peluncur. Karena ini berada di domain yang sama - tidak ada masalah lintas sumber. Itu juga bisa langsung memanggil metode global di halaman peluncur jika Anda tidak ingin menggunakan postMessage - mis.window.opener.someMethod(data)
Contoh (semua URL fiktif)
Halaman peluncur di
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>
Halaman proxy di
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>
Halaman jarak jauh di
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>
sumber
== SOLUSI KERJA DI 2020 tanpa iframe ==
Membangun jawaban dengan kusut, saya berhasil di IE11 [dan meniru mode IE10] menggunakan cuplikan berikut:
var submitWindow = window.open("/", "processingWindow"); submitWindow.location.href = 'about:blank'; submitWindow.location.href = 'remotePage to comunicate with';
Kemudian saya dapat berkomunikasi menggunakan tumpukan postMessage yang khas, saya menggunakan satu utusan statis global dalam skenario saya (meskipun saya tidak menganggap itu penting, saya juga melampirkan kelas messenger saya)
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; } }
Tidak peduli seberapa keras saya mencoba, saya tidak dapat membuat semuanya berfungsi di IE9 dan IE8
Konfigurasi saya di mana ini berfungsi:
Versi IE: 11.0.10240.16590, Perbarui versi: 11.0.25 (KB3100773)
sumber
Dibangun berdasarkan jawaban oleh LyphTEC dan Akrikos, solusi lain adalah membuat
<iframe>
dalam jendela sembulan kosong, yang menghindari kebutuhan untuk halaman proxy terpisah, karena sembulan kosong memiliki asal yang sama dengan pembukanya.Halaman peluncur di
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>
Halaman jarak jauh di
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>
Saya tidak yakin seberapa rapuh ini, tetapi berfungsi di IE 11 dan Firefox 40.0.3.
sumber
<iframe>
arah) di IE 11 (11.0.9600.18036
, perbarui versi11.0.23 (KB3087038)
). Mungkin pembaruan keamanan terkini ( KB3087038 ) terlibat.Saat ini, (2014-09-02), Taruhan terbaik Anda adalah menggunakan bingkai proxy seperti yang tercantum di entri blog msdn yang merinci solusi untuk masalah ini: https://blogs.msdn.microsoft.com/ieinternals/2009 / 09/15 / html5-implementation-issues-in-ie8-and-later /
Inilah contoh yang berfungsi: http://www.debugtheweb.com/test/xdm/origin/
Anda perlu menyiapkan bingkai proxy di halaman Anda yang memiliki asal yang sama dengan popup. Kirim informasi dari popup ke bingkai proxy menggunakan
window.opener.frames[0]
. Kemudian gunakan postMessage dari bingkai proxy ke halaman utama.sumber
Solusi ini melibatkan penambahan situs ke Situs Terpercaya Internet Explore dan bukan di situs Intranet Lokal. Saya menguji solusi ini di Windows 10 / IE 11.0.10240.16384, Windows 10 / Microsoft Edge 20.10240.16384.0 dan Windows 7 SP1 / IE 10.0.9200.17148. Halaman tidak boleh dimasukkan ke dalam Zona Intranet .
Jadi buka konfigurasi Internet Explorer (Tools> Internet Options> Security> Trusted Sites> Sites), dan tambahkan halaman, di sini saya menggunakan * untuk mencocokkan semua subdomain. Pastikan halaman tidak terdaftar di situs intranet lokal (Alat> Opsi Internet> Keamanan> Intranet Lokal> Situs> Lanjutan). Mulai ulang browser Anda dan uji lagi.
Di Windows 10 / Microsoft Edge Anda akan menemukan konfigurasi ini di Control Panel> Internet Options.
MEMPERBARUI
Jika ini tidak berhasil, Anda dapat mencoba mengatur ulang semua pengaturan Anda di Alat> Opsi Internet> Pengaturan Lanjutan> Atur ulang pengaturan Internet Explorer dan kemudian Atur Ulang: gunakan dengan hati - hati ! Kemudian Anda perlu me-reboot sistem Anda. Setelah itu tambahkan situs tersebut ke situs Terpercaya.
Lihat di zona apa halaman Anda berada di File> Properties atau gunakan klik kanan.
MEMPERBARUI
Saya menggunakan intranet perusahaan dan terkadang berfungsi dan terkadang tidak (konfigurasi otomatis? Saya bahkan mulai menyalahkan proxy perusahaan). Pada akhirnya saya menggunakan solusi ini https://stackoverflow.com/a/36630058/2692914 .
sumber
Q ini sudah lama tetapi untuk itulah easyXDM, mungkin memeriksanya sebagai kemungkinan fallback ketika Anda mendeteksi browser yang tidak mendukung html5 .postMessage:
https://easyxdm.net/
Ini menggunakan pembungkus VBObject dan semua jenis hal yang tidak ingin Anda tangani untuk mengirim pesan lintas domain antara jendela atau bingkai di mana window.postMessage gagal untuk berbagai versi IE (dan mungkin edge, masih tidak yakin 100% pada dukungan Edge memiliki tetapi tampaknya juga membutuhkan solusi untuk .postMessage)
sumber
MessageChannel tidak berfungsi untuk IE 9-11 di antara jendela / tab karena bergantung pada postMessage, yang masih rusak dalam skenario ini. Solusi "terbaik" adalah memanggil fungsi melalui window.opener (mis. Window.opener.somefunction ("somedata")).
Solusi lebih detail di sini
sumber