Komunikacja między dokumentami w różnych domenach
Bo w tym cały jest ambaras, żeby dwoje chciało naraz
Komunikacja między stronami
w różnych domenach
Same-origin policy
Dokumenty z różnych hostów / portów / protokołów nie mają dostępu do swojej treści:
parent.$("p")[0].innerHTML=":)";
// Error: permission denied
iframe.contentWindow.someFunction();
// Error: permission denied
document.domain
Dla stron z subdomen jednej domeny:
// xyz.example.org:
document.domain = "example.org";
// abc.example.org:
document.domain = "example.org";
iframe.src="http://xyz.example.org";
// ...
iframe.contentWindow.
$("#foo")[0].innerHTML = "oh hai";
Kiedy document.domain
nie jest OK:
- strony są w różnych TLD
- strony powinny tylko wysyłać komunikaty, nie wykonywać cudzy kod
Trik z iframes i location.hash
- strona A ma iframe z B, w której jest iframe z A
- komunikacja poprzez ustawienie #hash
YO DAWG WE HEARD YOU LIKE IFRAMES...
Jak to działa?
Strona odbierająca komunikaty:
function receiveMsg(e) {
if (e.origin == "http://doz.wo.lony") {
alert("Przyszło: " + e.data);
}
}
window.addEventListener("message",
receiveMsg, true);
Strona wysyłająca:
targetWin.postMessage("cześć", "http://do.cel.owy");
Przesyłanie obiektów
targetWin.postMessage(
JSON.stringify({
name: "Jan Nowak",
city: "Kraków"
}),
"http://do.cel.owy"
);
Na odbierającej:
// ...
var obiekt = JSON.parse(e.data);
Własności zdarzenia
e.data
- przesłane dane (string)
e.source
- referencja do okna wysyłającego
e.origin
- pochodzenie nadawcy (protokół, host, czasem też port),
np.
https://example.org
, http://example.com:4567
Funkcja postMessage
targetWin.postMessage(msg, targetOrigin);
targetWin
- zdalne okno lub
iframe.contentWindow
targetOrigin
- dozwolony origin (por.
e.origin
) lub "*"
Uwaga na "*"
Jeśli przekazujemy wrażliwe dane, zawsze określajmy targetOrigin
- w ramce mogło nastąpić przekierowanie.
Ale co z IE7?
- jeśli funkcjonalność ta jest tylko dodatkowym bajerem: dajmy sobie spokój z IE7
- jeśli funkcjonalność jest absolutnie niezbędna dla wszystkich: sztukujemy. Tylko jak?
Sztukowanie
- nie ma polyfilla sensu stricto
- EasyXDM
- zapewnia prawie identyczne API
- transport via natywne
postMessage
, Flash, zmiany hasha
- inne (np. jQuery.postMessage)
Dziękuję za uwagę. Pytania?
Image credits: HTML5 logo by the W3C.
Slides engine: dzSlides, under WTFPL.
Syntax highlighting thanks to highlight.js by Ivan Sagalaev (license)