Jak komunikować się między ramką iframe a witryną nadrzędną?


184

Strona internetowa w ramce iframe nie znajduje się w tej samej domenie , ale obie są moje i chciałbym się komunikować między iframewitryną nadrzędną a nią. Czy to możliwe?

Odpowiedzi:


307

W przypadku różnych domen nie można wywoływać metod ani uzyskiwać bezpośredniego dostępu do dokumentu treści iframe.

Musisz używać przesyłania wiadomości między dokumentami .

Na przykład w górnym oknie:

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

oraz w ramce iframe:

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

Jeśli publikujesz wiadomość z elementu iframe w oknie nadrzędnym

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

2
dziękuję, ale niestety nie działa w starszych przeglądarkach.
Danny Fox

106
W dominującej: window.onmesage = function().... W window.top.postMessage('hello', '*')
ramce

3
To nie jest błąd. Adresy plików mogą być bardzo niebezpieczne, a przeglądarki traktują je z coraz większą ostrożnością. W dawnych czasach można było umieścić link file://C:/Windows/system32/whateverna stronie internetowej i skierować go bezpośrednio do folderu systemowego użytkownika. Obecnie przeglądarki najczęściej ignorują kliknięcia takich linków. Uruchom serwer WWW i uzyskaj dostęp do swojego kodu, a zobaczysz, że błędy znikają.
Stijn de Witt

4
Jako dobrą praktykę nigdy nie używaj „*” jako celu. W rzeczywistości MDN mówi - „Zawsze podaj konkretny celOrigin, a nie *, jeśli wiesz, gdzie powinien znajdować się dokument drugiego okna. Brak określonego celu ujawnia dane, które wysyłasz do dowolnej zainteresowanej złośliwej witryny”.
rodiwa

2
Możemy nawet użyć, window.frames[index]aby uzyskać child frame ( <iframe>, <object>, <frame>), równoważne z getElementsByTagName("iframe")[index].contentWindow. Aby uzyskać obiekt okna nadrzędnego z ramek IFrame, lepiej jest użyć window.parent, ponieważ window.topreprezentuje najwyższe okno nadrzędne
phoenisx

46

Musi tu być, ponieważ zaakceptowano odpowiedź z 2012 roku

W 2018 roku i we współczesnych przeglądarkach możesz wysłać niestandardowe zdarzenie z iframe do okna nadrzędnego.

iframe:

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

rodzic:

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

PS: Oczywiście możesz wysyłać zdarzenia w przeciwnym kierunku w ten sam sposób.

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

1
Witaj, czy muszę to robić w tej samej domenie?
Guillaume Harari,


1
Należy zauważyć, że dispatchEventjest obsługiwany we wszystkich głównych przeglądarkach. IE9 była pierwszą wersją, w której się pojawiła, więc większość systemów operacyjnych teraz z nią współpracuje. caniuse.com/#search=dispatchEvent
Dan Atkinson

1
Za pomocą tej metody nie jestem w stanie komunikować się z nadrzędnego na iframe.
Avan

Tak, też nie mogę go uruchomić, iframe js ładuje się po oknie nadrzędnym, więc nie ma tam wiadomości msg po wysłaniu. dla mnie działa tylko od iframe do parent.
radtek

14

Ta biblioteka obsługuje HTML5 postMessage i starsze przeglądarki z funkcją resize + hash https://github.com/ternarylabs/porthole

Edycja: Teraz w 2014 r. Zużycie IE6 / 7 jest dość niskie, IE8 i przede wszystkim obsługa, postMessagewięc teraz sugeruję, aby po prostu z niego korzystać.

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


Z zastrzeżeniem, że IE8 / 9 obsługuje tylko łańcuchy caniuse.com/#search=postmessage (Zobacz znane problemy)
Harry

można to obejść, kodując obiekty zdarzeń do formatu json i dekodując je po drugiej stronie.
codewandler



1

Użyj, event.source.window.postMessageaby odesłać z powrotem do nadawcy.

Z iframe

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

Następnie od rodzica odpowiedz.

window.onmessage = (event) => {
    event.source.window.postMessage('GOT_YOU_IFRAME', '*')
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.