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.