[HTML5] Jak komunikować się między stronami za pomocą HTML5 postMessage API
This post is 13 years old. Browsers and tools may have changed since then, so check the code against current documentation before you use it.
Specyfikacja HTML5 zawiera wiele różnych API. Jednym z nich jest API do komunikowania się stron umieszczonych w ramkach (iframe) ze stroną główną. Tego typu komunikacja może być bardzo przydatna w różnego rodzaju aplikacjach internetowych i nie tylko, gdzie istnieje potrzeba komunikacji między zupełnie różnymi stronami znajdującymi się w różnych domenach.
W skrócie, window.postMessage API zachowuje się jak AJAX bez odwoływania się do backendu strony internetowej (na przykład do metod PHP czy też skryptów w node.js).
Section 1HTML5 postMessage API - strona źródłowa
Na początek należy przygotować stronę źródłową/główną, która będzie wysyłała wiadomości za pomocą postMessage API. Zaczniemy od kodu HTML:
1 2 3 4 5 6 7 8 9 | <form id="login" action="/"> <ul> <li><label for="username">Nazwa użytkownika:</label><input type="text" name="login" id="username"></li> <li><label for="password">Hasło:</label><input type="password" name="pass" id="password"></li> <li><input type="submit" value="Zaloguj"></li> </ul> </form> <iframe id="target" src="[adres-url-ramki]"></iframe> <p id="answer"></p> |
Przygotowano prosty formularz, ktory zawiera 2 pola do wypełnienia i przycisk wyślij. Do tak przygotowanego formularza zastosujemy następujący skrypt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | window.onload = function () { var iframe = document.getElementById('target').contentWindow; var form = document.getElementById('login'); var domain = 'http://demo.piotrnalepa.pl'; form.onsubmit = function (event) { event.preventDefault(); var data = { user : document.getElementById('username').value, pass : document.getElementById('password').value }; iframe.postMessage(data, domain); event.returnValue = false; return false; }; window.addEventListener('message', function (event) { if (event.origin !== domain) return; document.getElementById('answer').innerHTML = event.data; },false); }; |
Powyższy kod JS jest odpowiedzialny za przesłanie wiadomości do strony znajdującej się w ramce. Wykorzystałem tutaj czysty JS, który na pewno nie zadziała w IE8 i niżej (nie obsługują windows.addEventListener).
Po kliknięciu przycisku, następuje utworzenie obiektu z danymi podanymi przez użytkownika a następnie przesłanie tych danych do strony w ramce za pomocą iframe.postMessage, ktory przyjął 2 argumenty: dane i adres domeny docelowej, czyli adres strony w ramce. Dla strony źródłowej zdefiniowałem zachowanie się strony w momencie, gdy strona wywoła zdarzenie - message. Zdarzenie message jest jednym ze zdarzeń obsługiwanych przez JS, tak jak click, hover, mouseleave, itd. Gdy strona źródłowa otrzyma odpowiedź z ramki, to wyświetli jej treść w kontenerze o identyfikatorze #answer.
Section 2HTML5 postMessage API - strona docelowa/ramka
Teraz pora zająć się stroną docelową, ktora będzie przyjmowala dane z formularza na poprzedniej stronie i ewentualnie będzie mogła sobie je przetworzyć w razie potrzeby. Jej kod HTML wygląda następująco:
1 2 | <h2>To jest strona na zupełnie innym serwerze.</h2> <p id="message">A tu będzie przesłana wiadomość</p> |
Nic specjalnego, nagłówek oraz paragraf z identyfikatorem. W tamtym paragrafie będzie wyświetlona wiadomość ze strony źródłowej.
Kod JS, który będzie obslugiwal otrzymywanie wiadomości ze strony źródłowej wygląda nastepująco:
1 2 3 4 5 6 7 8 9 10 | window.addEventListener('message', function (event) { var message; if (event.origin !== 'https://blog.piotrnalepa.pl') { message = 'To nie jest wiadomość z bloga https://blog.piotrnalepa.pl<br/>, tylko z: ' + event.origin; } else { message = 'Oto dane jakie dostarczono: ' + JSON.stringify(event.data) + '<br/> z domeny: ' + event.origin; event.source.postMessage('Wiadomość otrzymano :)', event.origin); } document.getElementById('message').innerHTML = 'Wiadomość:<br/>' + message; }, false); |
Wywołano metodę, ktora nasłuchuje czy nie miało miejsce wydarzenie message, a jeśli tak to sprawdza czy adres strony źródlowej się zgadza z adresem zdefiniowanym w kodzie JS strony docelowej. To jest zabezpieczenie przed niepożądanymi zapytaniami z innych stron. W zależności od tego czy adres strony źródłowej się zgadza następują inne akcje (w tym przypadku, generowana jest inna wiadomość). Następnie, do kontenera o identyfikatorze #message wstawiana jest treść wiadomości, a na końcu następuje wysłanie wiadomości zwrotnej do strony źródłowej, że wiadomość otrzymano. Należy zwrócić uwagę, że adres strony źródłowej jest zawarty w event.source i to na nim wykonujemy akcję postMessage.
Section 3HTML5 postMessage API - podsumowanie
Jak widać, nie trzeba koniecznie wykonywać zapytań AJAX-owych aby otrzymać dane z innych stron. Można równie dobrze wykorzystać do tego postMessage API. Dzięki temu, cała akcja dzieje się po stronie frontendu, czyli przeglądarki użytkownika. W podstawowym założeniu, miało to na celu uniknięcie wykonywania zapytań AJAX do skyptów serwerowych, jeśli istniała możliwość przechowywania potrzebnych danych w wygenerowanej ramce.
Mam nadzieję, że będzie to przydatny tekst i pozwoli Ci to na stworzenie wielu ciekawych funkcjonalności w oparciu o tą technologię, która jest właściwie wspierana we wszystkich popularnych przeglądarkach.
| Przeglądarka | wsparcie |
|---|---|
![]() |
tak |
![]() |
tak |
![]() |
nie |
![]() |
tak |
![]() 7/8/9/10 |
nie/tak/tak/tak |
Demo z tego artykułu można zobaczyć tutaj: HTML5 postMessage demo




