Как общаться между 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.