Bagaimana cara berkomunikasi antara iframe dan situs induk?


185

Situs web di iframe tidak terletak di domain yang sama , tetapi keduanya milik saya, dan saya ingin berkomunikasi antara iframesitus induk dan. Apa itu mungkin?

Jawaban:


308

Dengan domain yang berbeda, tidak mungkin untuk memanggil metode atau mengakses dokumen konten iframe secara langsung.

Anda harus menggunakan pesan lintas dokumen .

Misalnya di jendela atas:

 myIframe.contentWindow.postMessage('hello', '*');

dan di iframe:

window.onmessage = function(e){
    if (e.data == 'hello') {
        alert('It works!');
    }
};

Jika Anda memposting pesan dari iframe ke jendela induk

window.top.postMessage('hello', '*')

2
terima kasih, tetapi sayangnya itu tidak berfungsi di browser lama.
Danny Fox

106
Dalam orangtua: window.onmesage = function().... Di iframe:window.top.postMessage('hello', '*')
user123444555621

3
Itu bukan bug. URL file bisa sangat tidak aman dan browser memperlakukannya dengan perawatan yang semakin meningkat. Kembali di masa lalu Anda bisa meletakkan tautan file://C:/Windows/system32/whateverdi halaman web dan membuatnya langsung ke folder sistem pengguna. Saat ini sebagian besar browser mengabaikan klik pada tautan seperti itu. Jalankan server web dan akses kode Anda melalui itu dan Anda akan melihat kesalahan muncul.
Stijn de Witt

4
Sebagai praktik yang baik, jangan pernah menggunakan '*' untuk target Anda. Faktanya, MDN mengatakan - "Selalu berikan target tertentuOrigin, bukan *, jika Anda tahu di mana dokumen jendela lain harus ditempatkan. Gagal memberikan target spesifik mengungkapkan data yang Anda kirim ke situs berbahaya yang tertarik."
rodiwa

2
Kita bahkan dapat menggunakan window.frames[index]untuk mendapatkan bingkai anak ( <iframe>, <object>, <frame>), setara dengan getElementsByTagName("iframe")[index].contentWindow. Untuk mendapatkan Objek Jendela Induk dari IFrames, lebih baik menggunakan window.parent, karena window.topmewakili Jendela Paling Banyak Induk
phoenisx

46

Itu harus di sini, karena jawaban yang diterima dari 2012

Pada 2018 dan browser modern, Anda dapat mengirim acara khusus dari iframe ke jendela induk.

iframe:

var data = { foo: 'bar' }
var event = new CustomEvent('myCustomEvent', { detail: data })
window.parent.document.dispatchEvent(event)

induk:

window.document.addEventListener('myCustomEvent', handleEvent, false)
function handleEvent(e) {
  console.log(e.detail) // outputs: {foo: 'bar'}
}

PS: Tentu saja, Anda bisa mengirim acara dengan arah yang berlawanan dengan cara yang sama.

document.querySelector('#iframe_id').contentDocument.dispatchEvent(event)

1
Halo, apakah saya harus berada di domain yang sama untuk melakukannya?
Guillaume Harari


1
Perlu dicatat bahwa dispatchEventdidukung di semua browser utama. IE9 adalah versi pertama yang masuk, jadi sebagian besar OS sekarang bekerja dengannya. caniuse.com/#search=dispatchEvent
Dan Atkinson

1
Saya tidak dapat berkomunikasi dari orang tua ke iframe dengan metode ini.
Avan

Ya saya juga tidak bisa membuatnya berfungsi, iframe js sedang memuat setelah jendela induk sehingga tidak ada untuk menerima pesan ketika dikirim. itu hanya berfungsi dari iframe ke induk bagi saya.
radtek

14

Perpustakaan ini mendukung HTML5 postMessage dan browser lama dengan mengubah ukuran + hash https://github.com/ternarylabs/porthole

Sunting: Sekarang pada tahun 2014, penggunaan IE6 / 7 cukup rendah, IE8 dan di atas semua dukungan postMessagejadi saya sekarang menyarankan untuk hanya menggunakan itu.

https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage


Dengan peringatan bahwa IE8 / 9 hanya mendukung string caniuse.com/#search=postmessage (Lihat masalah yang diketahui)
Harry

ini bisa diselesaikan dengan menyandikan objek acara Anda ke json dan mendekodekannya di sisi lain.
codewandler



1

Gunakan event.source.window.postMessageuntuk mengirim kembali ke pengirim.

Dari Iframe

window.top.postMessage('I am Iframe', '*')
window.onmessage = (event) => {
    if (event.data === 'GOT_YOU_IFRAME') {
        console.log('Parent received successfully.')
    }
}

Kemudian dari orangtua katakan kembali.

window.onmessage = (event) => {
    event.source.window.postMessage('GOT_YOU_IFRAME', '*')
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.