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?

Danny Fox
sumber

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', '*')
pengguna123444555621
sumber
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)
Asing di Q
sumber
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

jpillora
sumber
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
3

yang window.topproperti harus dapat memberikan apa yang Anda butuhkan.

Misalnya

alert(top.location.href)

Lihat http://cross-browser.com/talk/inter-frame_comm.html

sambomartin
sumber
10
Karena iframe tidak berada di domain yang sama, ia tidak dapat mengakses induknya.
Andreas Köberle
1

Anda juga bisa menggunakan

postMessage(message, '*');

gonzarodriguezt
sumber
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', '*')
}
Binh Ho
sumber