Bagaimana Anda menggunakan window.postMessage di seluruh domain?

89

Sepertinya inti dari window.postMessage adalah untuk memungkinkan komunikasi yang aman antara windows / frame yang dihosting di domain yang berbeda, tetapi tampaknya tidak mengizinkannya di Chrome.

Berikut skenarionya:

  1. Sematkan <iframe> (dengan srcdi domain B * ) di halaman di domain A
  2. <iframe> akhirnya menjadi tag <script>, yang akhirnya dieksekusi ...
  3. Saya memanggil window.postMessage ( some_data , page_on_A )

<iframe> paling pasti dalam konteks domain B, dan saya telah mengonfirmasi bahwa javascript yang disematkan di <iframe> itu dijalankan dengan benar dan memanggil postMessagedengan nilai yang benar.

Saya mendapatkan pesan kesalahan ini di Chrome:

Tidak dapat mengirim pesan ke A . Penerima berawal B .

Berikut kode yang mendaftarkan pendengar peristiwa pesan di halaman di A:

window.addEventListener(
  "message",
  function (event) {
    // Do something
  },
  false);

Saya juga mencoba menelepon window.postMessage(some_data, '*'), tetapi yang dilakukannya hanyalah menekan kesalahan.

Apakah saya hanya melewatkan intinya di sini, apakah window.postMessage (...) tidak dimaksudkan untuk ini? Atau apakah saya melakukannya dengan sangat salah?

* Teks / html tipe pantomim, yang harus tetap ada.

Kevin Montrose
sumber
1
Anda mungkin sudah mengetahui hal ini, tetapi MDC memiliki rundown yang sangat bagus di postMessage: developer.mozilla.org/en/DOM/window.postMessage Untuk implementasi FF jelas, tapi mungkin ada sesuatu di sana yang menjelaskan mengapa itu tidak berhasil.
Pekka

Jawaban:

79

Berikut adalah contoh yang berfungsi di Chrome 5.0.375.125.

Halaman B (konten iframe):

<html>
    <head></head>
    <body>
        <script>
            top.postMessage('hello', 'A');
        </script>
    </body>
</html>

Perhatikan penggunaan top.postMessageatau parent.postMessagetidak window.postMessagedi sini

Halaman A:

<html>
<head></head>
<body>
    <iframe src="B"></iframe>
    <script>
        window.addEventListener( "message",
          function (e) {
                if(e.origin !== 'B'){ return; } 
                alert(e.data);
          },
          false);
    </script>
</body>
</html>

A dan B pasti seperti itu http://domain.com

EDIT:

Dari pertanyaan lain , terlihat domain (A dan B di sini) harus memiliki /untuk postMessageberfungsi dengan benar.

Mikrofon
sumber
3
Ketika halaman A memeriksa keaslian pesan, asalnya TIDAK akan mengandung tanda '/'. Tampaknya tidak masalah jika halaman B mencantumkan tanda '/' atau tidak. Hal lain yang perlu diperhatikan adalah bahwa URL harus menjadi URL mutlak.
Tonton
1
Jawaban ini membuat saya sedikit bingung dan masih mencari jawaban. blog.teamtreehouse.com/cross-domain-messaging-with-postmessage berisi penjelasan yang sangat bagus tentang postMessage. Yang penting pengirim pesan mengetahui domain penerima. Dalam contoh di atas, A dan B tidak harus domain yang sama, tetapi B harus tahu persis domain apa yang digunakan oleh A.
Greg Bogumil
7
Pertanyaannya adalah tentang lintas domain. Jawaban yang diterima adalah tentang domain yang sama.
stackular
@ackular, tidak persis. A dan B dapat berupa domain apa saja. Itulah alasan utama mengadakanpostMessage
Mic
1
+1. Kami ingin mengonfirmasi bahwa solusi ini berhasil pada kasus kami. Kami memiliki halaman yang berisi iframe dari domain berbeda . Harap diperhatikan bahwa ini hanya berfungsi di browser Chrome, karena di firefox kita perlu menggunakan window.parent.postMessage alih-alih top . Meskipun kami tidak tahu apakah ini dapat diterapkan ke browser lain.
rahmatns
24

Anda harus memposting pesan dari frame ke orang tua, setelah dimuat.

skrip bingkai:

$(document).ready(function() {
    window.parent.postMessage("I'm loaded", "*");
});

Dan dengarkan sebagai orang tua:

function listenMessage(msg) {
    alert(msg);
}

if (window.addEventListener) {
    window.addEventListener("message", listenMessage, false);
} else {
    window.attachEvent("onmessage", listenMessage);
}

Gunakan tautan ini untuk info lebih lanjut: http://en.wikipedia.org/wiki/Web_Messaging

Golyo
sumber
2

Mungkin Anda mencoba mengirim data Anda dari mydomain.com ke www.mydomain.com atau sebaliknya, CATATAN Anda melewatkan "www". http://mydomain.com dan http://www.mydomain.com adalah domain yang berbeda dengan javascript.

Getoriks
sumber
2
Dalam sebuah proyek yang saya lakukan, saya menggunakan file:/// Apakah mungkin mendapatkan kesalahan domain saat menarik konten hanya dari sistem file lokal?
Jacksonkr