Domainler arasında window.postMessage'ı nasıl kullanıyorsunuz?


89

Window.postMessage'ın amacı, farklı alanlarda barındırılan pencereler / çerçeveler arasında güvenli iletişime izin vermek gibi görünüyor , ancak aslında Chrome'da buna izin vermiyor gibi görünüyor .

İşte senaryo:

  1. A etki alanındaki bir sayfaya bir <iframe> ( srcB * etki alanında a ile) yerleştirin
  2. <iframe>, çoğunlukla yürütmenin sonunda bir <script> etiketi olur ...
  3. Window.postMessage ( bazı_veriler , sayfa_on_A ) çağırıyorum

<iframe>, kesinlikle B etki alanı bağlamındadır ve bu <iframe> içindeki gömülü javascript'in düzgün çalıştığını ve postMessagedoğru değerlerle çağırdığını doğruladım .

Bu hata mesajını Chrome'da alıyorum:

A'ya mesaj gönderilemiyor . Alıcının kaynağı B'dir .

İşte A'daki sayfada bir mesaj olay dinleyicisini kaydeden kod:

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

Aramayı da denedim window.postMessage(some_data, '*'), ancak tek yaptığı hatayı bastırmak.

Buradaki noktayı mı kaçırıyorum, window.postMessage (...) bunun için değil mi? Yoksa bunu korkunç derecede yanlış mı yapıyorum?

* Kalması gereken mime tipi metin / html.


1
Muhtemelen bunun zaten farkındasınız, ancak MDC'nin postMessage'da mükemmel bir özeti var: developer.mozilla.org/en/DOM/window.postMessage FF uygulaması için tabii ki, ama belki de orada neden çalışmadığını açıklayan bir şey var.
Pekka

Yanıtlar:


79

İşte Chrome 5.0.375.125'te çalışan bir örnek.

B sayfası (iframe içeriği):

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

Kullanımına dikkat top.postMessageveya parent.postMessagedeğil window.postMessageburada

A sayfası:

<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 ve B gibi bir şey olmalı http://domain.com

DÜZENLE:

Gönderen başka bir soru , bu etki (burada A ve B) olması gerekir görünüyor /için postMessagedüzgün çalışması için.


3
Sayfa A mesajın kaynağını kontrol ettiğinde, başlangıçta "/" harfi İÇERMEZ. Sayfanın B'nin sonunda bir '/' belirtip belirtmemesi önemli görünmüyor. Unutulmaması gereken diğer bir nokta da URL'lerin mutlak URL'ler olması gerektiğidir.
Catch 22

1
Bu cevap beni biraz karıştırdı ve hala bir cevap arıyordu. blog.teamtreehouse.com/cross-domain-messaging-with-postmessage , postMessage'ın çok iyi bir açıklamasını içerir. Önemli olan, mesajı gönderenin alıcının alanını bilmesidir. Yukarıdaki örnekte, A ve B aynı etki olması gerekmez, ama B A. tarafından kullanılan tam olarak ne alanı bilmelidir
Greg Bogumil

7
Soru, alanlar arası ile ilgili. Kabul edilen cevap aynı alanla ilgilidir.
stackular

@stackular, tam olarak değil. A ve B herhangi bir alan olabilir. Sahip olmanın ana nedeni budurpostMessage
Mic

1
+1. Bu çözümün davamızda işe yaradığını doğrulamak istiyoruz. Farklı etki alanından bir iframe içeren bir sayfamız var . Lütfen bunun yalnızca Chrome tarayıcısında çalıştığını unutmayın, çünkü firefox'ta top yerine window.parent.postMessage kullanmamız gerekir . Bunun başka bir tarayıcıya uygulanıp uygulanamayacağını bilmiyoruz.
rahmatns

24

Yükledikten sonra çerçeveden ebeveyne bir mesaj göndermelisiniz.

çerçeve komut dosyası:

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

Ve ebeveynlerden dinleyin:

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

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

Daha fazla bilgi için bu bağlantıyı kullanın: http://en.wikipedia.org/wiki/Web_Messaging


2

Muhtemelen verilerinizi mydomain.com'dan www.mydomain.com'a göndermeye veya tersine göndermeye çalışırsınız, NOT "www" kaçırmışsınızdır. http://mydomain.com ve http://www.mydomain.com javascript farklı etki alanlarıdır.


2
Yaptığım bir projede, kullanıyorum file:/// İçeriği yalnızca yerel dosya sisteminden çekerken etki alanı hataları almak mümkün mü?
Jacksonkr
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.