Як спілкуватися між iframe та батьківським сайтом?


185

Веб-сайт у iframe розташований не в одному домені , але обидва є моїми, і я хотів би спілкуватися між iframeбатьківським сайтом та його батьків. Це можливо?

Відповіді:


307

З різними доменами неможливо викликати методи або отримати доступ до документа зі змістом iframe безпосередньо.

Ви повинні використовувати перехресні документи .

Наприклад, у верхньому вікні:

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

і в iframe:

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

Якщо ви публікуєте повідомлення з iframe у батьківське вікно

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

2
дякую, але, на жаль, це не працює у старих браузерах.
Danny Fox

106
У батьків: window.onmesage = function().... У iframe:window.top.postMessage('hello', '*')
користувач123444555621

3
Це не помилка. URL-адреси файлів можуть бути дуже небезпечними, і веб-переглядачі ставляться до них із все більшою обережністю. Ще в давні часи можна було розмістити посилання file://C:/Windows/system32/whateverна веб-сторінку і зробити так, щоб вона вказувала прямо в системну папку користувача. Сьогодні браузери здебільшого ігнорують кліки на таких посиланнях. Запустіть веб-сервер і отримайте доступ до свого коду через це, і ви побачите, що помилки зникають.
Штійн де Вітт

4
Як хороша практика, ніколи не використовуйте "*" для своєї цілі. Насправді, MDN каже: "Завжди надайте конкретну targetOrigin, а не *, якщо ви знаєте, де повинен знаходитися документ іншого вікна. Якщо не вказати конкретну ціль, розкриваються дані, які ви надсилаєте на будь-який зацікавлений шкідливий сайт".
rodiwa

2
Ми навіть можемо використовувати window.frames[index]дочірній кадр ( <iframe>, <object>, <frame>), еквівалентний getElementsByTagName("iframe")[index].contentWindow. Щоб отримати об'єкт Parent Window від IFrames, краще використовувати window.parent, як це window.topявляє собою Найпопулярніше вікно для батьків
phoenisx

46

Це повинно бути тут, бо прийняли відповідь з 2012 року

У 2018 році та сучасних браузерах ви можете надіслати власну подію з iframe до батьківського вікна.

iframe:

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

батьків:

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

PS: Звичайно, ви можете відправляти події у зворотному напрямку аналогічним чином.

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

1
Привіт, чи повинен я бути в одному домені, щоб це зробити?
Гійом Харарі


1
Слід зазначити, що dispatchEventце підтримується у всіх основних браузерах. IE9 була першою версією, в яку вона з'явилася, тому більшість ОС зараз працює з нею. caniuse.com/#search=dispatchEvent
Ден Аткінсон

1
Я не в змозі спілкуватися від батьків до iframe цим методом.
Аван

Так, я також не можу змусити його працювати, iframe js завантажується після батьківського вікна, тому він не існує, щоб отримувати повідомлення при надсиланні. для мене це працює лише від iframe до батьківського.
радтек

14

Ця бібліотека підтримує HTML5 postMessage і застарілі браузери з розміром + хеш https://github.com/ternarylabs/porthole

Редагувати: Зараз у 2014 році використання IE6 / 7 є досить низьким, IE8 і перш за все підтримкою, postMessageтому я пропоную просто скористатися цим.

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


З застереженням, що IE8 / 9 підтримує лише рядки caniuse.com/#search=postmessage (Див. Відомі проблеми)
Гаррі

це можна вирішити, кодуючи об’єкти події до json та декодуючи їх з іншого боку.
кодовера



1

Використовуйте event.source.window.postMessageдля повернення відправнику.

Від Іфрейму

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

Потім від батьків скажіть назад.

window.onmessage = (event) => {
    event.source.window.postMessage('GOT_YOU_IFRAME', '*')
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.