Как общаться между iframe и родительским сайтом?


185

Веб-сайт в iframe не находится в одном домене , но оба они мои, и я хотел бы установить связь между iframeродительским сайтом и. Является ли это возможным?

Ответы:


309

Для разных доменов невозможно вызвать методы или получить прямой доступ к документу содержимого iframe.

Вы должны использовать обмен сообщениями между документами .

Например в верхнем окне:

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

и в фрейме:

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

Если вы отправляете сообщение из iframe в родительское окно

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

2
спасибо, но, к сожалению, это не работает в старых браузерах.
— Дэнни Фокс

106
В родителю: window.onmesage = function().... В window.top.postMessage('hello', '*')
— фрейме

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

4
Как хорошая практика, никогда не используйте «*» для вашей цели. На самом деле, MDN говорит: «Всегда указывайте конкретный targetOrigin, а не *, если вы знаете, где должен находиться документ другого окна. Если вы не укажете конкретную цель, обнаружатся данные, которые вы отправляете на любой заинтересованный вредоносный сайт».
— Родива

2
Мы можем даже использовать, window.frames[index]чтобы получить child frame ( <iframe>, <object>, <frame>), эквивалентный getElementsByTagName("iframe")[index].contentWindow. Чтобы получить объект родительского окна из 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 до parent для меня.
— Радтек

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 (см. Известные проблемы)
— Harry

это можно обойти, кодируя объекты событий в json и декодируя их на другой стороне.
— Codewandler



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.