IE10'da çapraz kaynaklı postMessage bozuk mu?


91

Önemsiz bir postMessageörnek yapmaya çalışıyorum ...

  • IE10'da
  • pencereler / sekmeler arasında (iframe'lerle karşılaştırıldığında)
  • kökenler arasında

Bu koşullardan herhangi birini kaldırırsanız her şey yolunda gider :-)

Ancak anlayabildiğim kadarıyla, pencere arası postMessagesadece IE10'da her iki pencere de bir orijini paylaştığında çalışıyor gibi görünüyor. (Aslında - ve tuhaf bir şekilde - davranış bundan biraz daha müsamahakar: bir ev sahibini paylaşan iki farklı köken de işe yarıyor gibi görünüyor).

Bu belgelenmiş bir hata mı? Herhangi bir geçici çözüm veya başka bir tavsiye?

(Not: Bu soru konulara değinmektedir, ancak cevabı IE8 ve IE9 hakkındadır - 10 değil)


Daha fazla ayrıntı + örnek ...

başlatıcı sayfası demosu

<!DOCTYPE html>
<html>
  <script>
    window.addEventListener("message", function(e){
      console.log("Received message: ", e);
    }, false);
  </script>
  <button onclick="window.open('http://jsbin.com/ameguj/1');">
    Open new window
  </button>
</html>

başlatılan sayfa demosu

<!DOCTYPE html>
<html>
  <script>
    window.opener.postMessage("Ahoy!", "*");
  </script>
</html>

Bu şu adreste çalışır: http://jsbin.com/ahuzir/1 - çünkü her iki sayfa da aynı kaynakta barındırılır (jsbin.com). Ancak ikinci sayfayı başka bir yere taşıyın ve IE10'da başarısız olur.



5
Lütfen, MessageChannel'in çalışmasını sağlamak için postMessage gerektirdiğinde, en iyi bahsiniz olarak MessageChannel'i listeleyen bir yanıt yerine, soruyu yanıtlayan bir yanıt olarak kabul edilen yanıtı değiştirmeyi düşünün. Yalnızca geçerli çözümün bir iframe proxy'si olduğunu bulmak için MessageChannel ile bir saatten fazla oynadım.
Akrikos

1
Window.open yalnızca bir açılır pencere iletişim kutusuysa, bunu tamamen önleyebilir ve js modal'da bir iframe kullanabilirsiniz. JQuery Dialog veya Bootstrap Modal gibi bir şey , onu nasıl uyguladığımdır. O zaman window.parent.postMessageIE'de kullanabilirsiniz .
styfle

Benim cevap olarak @Bosh o hala eski ie desteklemek zorunda talihsiz olanlar bize yardım görünüyor gibi kabul cevap olarak thatone ayarı misin, 2018 yılında çalışmalarına görünüyor ve hiçbir vekil çerçeve gerektirir
Bruno Laurinec

Yanıtlar:


62

Bu cevabı ilk gönderdiğimde yanılmışım: aslında IE10'da çalışmıyor. Görünüşe göre insanlar bunu başka nedenlerden dolayı yararlı buldular, bu yüzden onu gelecek nesillere bırakıyorum. Aşağıdaki orijinal cevap:


postMessageDikkate değer: Bu yanıttaki bağlantı, IE8 ve IE9'daki ayrı pencereler için çapraz orijinli olmayan durumlara bağladığınız - ancak, IE10 gelmeden önce 2009'da da yazılmıştır. Bu yüzden bunu IE10'da düzeltildiğinin bir göstergesi olarak kabul etmem.

postMessageKendisine gelince , http://caniuse.com/#feat=x-doc-messaging , demonuzla eşleşiyor gibi görünen IE10'da hala bozuk olduğunu gösteriyor. Caniuse sayfası , çok alakalı bir alıntı içeren bu makaleye bağlantı verir :

Internet Explorer 8+, belgeler arası mesajlaşmayı kısmen destekler: şu anda iç çerçevelerle çalışır, ancak yeni pencerelerle çalışmaz. Ancak Internet Explorer 10, MessageChannel'ı destekleyecektir. Firefox şu anda belgeler arası mesajlaşmayı destekliyor ancak MessageChannel'i desteklemiyor.

Dolayısıyla en iyi seçeneğiniz muhtemelen MessageChanneltemel bir kod yoluna sahip olmak ve postMessagebu yoksa geri dönüş yapmaktır . Size IE8 / IE9 desteği sağlamaz, ancak en azından IE10 ile çalışacaktır.

Dokümanlar MessageChannel: http://msdn.microsoft.com/en-us/library/windows/apps/hh441303.aspx


8
MessageChannelÇalışan tabanlı bir kod yolunu nasıl yaratırsınız? postMessageKanalın bağlantı noktasını diğer pencereye taşımak için hala çalışmanız gerekir .
balpha

1
postMessageYeni MessageChannelAPI ile birlikte kullanmak , yeni pencerelerde ve başlangıç ​​noktalarında çalışacaktır. Çalışmak biraz garip sanırım, ama temelde: postMessage('foo', '*')kötü, postMessage('foo', [messageChannel.port2])iyi.
ShZ

3
IE'nin (11) en son sürümünü ve MessageChannel API'sini kullanarak postMessage'ın etki alanları arası açılır pencere ile çalışmasını ömür boyu elde edemiyorum. Ve dürüst olmak gerekirse, bu özel senaryonun çalışması gerektiğini belirten bu cevap dışında InterWebs'de başka bir yer bulamıyorum. İşe yaradığını kanıtlayan bir örneğe kimse işaret edebilir mi? Sonsuza kadar minnettar olurum.
Todd Menier

4
MessageChannel, postMessage'ın çalışmayacağı aynı nedenle çalışmamalıdır. Microsoft'un süreçler arası sıralamayı düzeltmesi gerekiyor. blogs.msdn.com/b/ieinternals/archive/2009/09/15/…
EricLaw

9
Bu cevap can sıkıcı çünkü bize yanlış umut veriyor. Cevap şu: bir proxy olmadan çalışmayacak çünkü MessageChannel'in çalışması için postMessage gerekiyor (en azından gördüğüm her demoda). Birisi bana postMessage veya postMessage ('name', '<domain>', [messageChannel.port2]) etki alanları arası çalışan bir MessageChannel demosu göstermediği sürece (işe yarayamam) buna inanmayacağım proxy çerçevesi olmadan çalışır.
Akrikos

30

Başlatıcı ile aynı ana bilgisayarda bir proxy sayfası oluşturun. Proxy sayfasının iframekaynağı uzak sayfaya ayarlanmış. Çapraz kökenli postMessage artık IE10'da şu şekilde çalışacak:

  • Uzak sayfa, window.parent.postMessageverileri proxy sayfasına geçirmek için kullanır . Bu iframe'leri kullandığından, IE10 tarafından desteklenir
  • Proxy sayfası, window.opener.postMessageverileri başlatıcı sayfasına geri göndermek için kullanır . Bu aynı etki alanında olduğu için - çapraz kaynak sorunu yoktur. Ayrıca postMessage'ı kullanmak istemiyorsanız, başlatıcı sayfasında doğrudan global yöntemleri çağırabilir - örn.window.opener.someMethod(data)

Örnek (tüm URL'ler hayalidir)

Adresindeki Başlatıcı sayfası http://example.com/launcher.htm

<!DOCTYPE html>
<html>
    <head>
        <title>Test launcher page</title>
        <link rel="stylesheet" href="/css/style.css" />
    </head>
    <body>

    <script>
        function log(msg) {
            if (!msg) return;

            var logger = document.getElementById('logger');
            logger.value += msg + '\r\n';
        }            

        function toJson(obj) {
            return JSON.stringify(obj, null, 2);
        }

        function openProxy() {
            var url = 'proxy.htm';
            window.open(url, 'wdwProxy', 'location=no');
            log('Open proxy: ' + url);
        }

        window.addEventListener('message', function(e) {
            log('Received message: ' + toJson(e.data));
        }, false);
    </script>
    
    <button onclick="openProxy();">Open remote</button> <br/>
    <textarea cols="150" rows="20" id="logger"></textarea>

    </body>
</html>

Adresindeki proxy sayfası http://example.com/proxy.htm

<!DOCTYPE html>
<html>
    <head>
        <title>Proxy page</title>
        <link rel="stylesheet" href="/css/style.css" />
    </head>
    <body>

    <script>
        function toJson(obj) {
            return JSON.stringify(obj, null, 2);
        }

        window.addEventListener('message', function(e) {
            console.log('Received message: ' + toJson(e.data));

            window.opener.postMessage(e.data, '*');
            window.close(self);
        }, false);
    </script>

    <iframe src="http://example.net/remote.htm" frameborder="0" height="300" width="500" marginheight="0" marginwidth="0" scrolling="auto"></iframe>

    </body>
</html>

Uzak sayfa http://example.net/remote.htm

<!DOCTYPE html>
<html>
    <head>
        <title>Remote page</title>
        <link rel="stylesheet" href="/css/style.css" />
    </head>
    <body>

    <script>
        function remoteSubmit() {
            var data = {
                message: document.getElementById('msg').value
            };

            window.parent.postMessage(data, '*');
        }
    </script>
    
    <h2>Remote page</h2>

    <input type="text" id="msg" placeholder="Type a message" /><button onclick="remoteSubmit();">Close</button>

    </body>
</html>

Yanıtınız, Microsoft örnek sayfasına ve diğer yanıtlarda bağlantı verilen geçici çözüm sayfasına bir bağlantı içeriyorsa daha iyi olur. Çözüm: blogs.msdn.com/b/ieinternals/archive/2009/09/16/… Örnek (geçici çözüm sayfasından): debugtheweb.com/test/xdm/origin
Akrikos

Ayrıca, örnek sayfanız artık bulunmayan bir godaddy sayfasına bağlantı veriyor.
Akrikos

8
ha? ... tüm URL'ler ÖRNEKTİR ve gerçekte mevcut sayfalara işaret etme amacı
taşımazlar

Açıklama için teşekkürler. :-)
Akrikos

29

== 2020'DE iframe olmadan ÇALIŞAN ÇÖZÜM ==

Dolaşarak yanıt üzerine inşa ederek, aşağıdaki snippet'i kullanarak IE11'de başarılı oldum [ve IE10 modunu taklit ettim]:

var submitWindow = window.open("/", "processingWindow");
submitWindow.location.href = 'about:blank';
submitWindow.location.href = 'remotePage to comunicate with';

Sonra tipik postMessage yığınını kullanarak iletişim kurabildim, senaryomda bir global statik messenger kullanıyorum (bunun herhangi bir önemi olduğunu sanmıyorum, ancak mesajlaşma sınıfımı da ekliyorum)

var messagingProvider = {
    _initialized: false,
    _currentHandler: null,

    _init: function () {
        var self = this;
        this._initialized = true;
        var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
        var eventer = window[eventMethod];
        var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";

        eventer(messageEvent, function (e) {
            var callback = self._currentHandler;
            if (callback != null) {
                var key = e.message ? "message" : "data";
                var data = e[key];
                callback(data);
            }
        }, false);
    },

    post: function (target, message) {
        target.postMessage(message, '*');
    },

    setListener: function (callback) {
        if (!this._initialized) {
            this._init();
        }

        this._currentHandler = callback;
    }
}

Ne kadar uğraşırsam uğraşayım, IE9 ve IE8'de işleri yürütemedim

Çalıştığı yerde yapılandırmam:
IE sürümü: 11.0.10240.16590, Güncelleme sürümleri: 11.0.25 (KB3100773)


6
Şunu söylemeliyim ki - başka biri bu geçici çözüme bakıyorsa "hayır, bu onu düzeltemez" diye düşünüyorsa - evet, aslında IE11'de window.opener'a mesaj gönderme yetersizliğini düzeltti. Inanılmaz.
dkr88


takılar gibi çalışır ve gizemli !! (IE10.0.9200, win7)
Simon

Bu geçici çözüm için tam bir Örnek verebilir misiniz?
msm2020

1
@SidJonnala gerçekten değil, ama bunu tavsiye ederim. Gerçek uzak sayfayı hemen yeniden atarsanız ve sayfanızın yüklenmesi 3-4 saniye sürerse [zaman zaman olabilir], window.open ('/') sayfanızın yüklenmesi ve kullanıcıyı şaşırtması
riskini alırsınız

2

LyphTEC ve Akrikos'un yanıtlarına dayanarak, başka bir çözüm, <iframe>boş bir açılır pencere içinde bir boş açılır pencere oluşturmaktır, bu da boş bir açılır pencerenin açıcısı ile aynı kökene sahip olması nedeniyle ayrı bir proxy sayfası ihtiyacını ortadan kaldırır.

Adresindeki Başlatıcı sayfası http://example.com/launcher.htm

<html>
  <head>
    <title>postMessage launcher</title>
    <script>
      function openWnd() {
        var w = window.open("", "theWnd", "resizeable,status,width=400,height=300"),
            i = w.document.createElement("iframe");

        i.src = "http://example.net/remote.htm";
        w.document.body.appendChild(i);

        w.addEventListener("message", function (e) {
          console.log("message from " + e.origin + ": " + e.data);

          // Send a message back to the source
          e.source.postMessage("reply", e.origin);
        });
      }
    </script>
  </head>
  <body>
    <h2>postMessage launcher</h2>
    <p><a href="javascript:openWnd();">click me</a></p>
  </body>
</html>

Uzak sayfa http://example.net/remote.htm

<html>
  <head>
    <title>postMessage remote</title>
    <script>
      window.addEventListener("message", function (e) {
        alert("message from " + e.origin + ": " + e.data);
      });

      // Send a message to the parent window every 5 seconds
      setInterval(function () {
        window.parent.postMessage("hello", "*");
      }, 5000);
    </script>
  </head>
  <body>
    <h2>postMessage remote</h2>
  </body>
</html>

Bunun ne kadar kırılgan olduğundan emin değilim, ancak IE 11 ve Firefox 40.0.3'te çalışıyor.


1
... ve şimdi <iframe>IE 11'de ( 11.0.9600.18036, güncelleme sürümleri 11.0.23 (KB3087038)) çalışmıyor (açılır pencerede yöne doğru sessiz hata ). Muhtemelen en son güvenlik güncelleştirmesi ( KB3087038 ) bulaşmıştır .
arapsaçı

1

Şu anda, (2014-09-02), yapabileceğiniz en iyi şey, msdn blog gönderisinde belirtildiği gibi bu sorun için bir geçici çözümün ayrıntılarını veren bir proxy çerçevesi kullanmaktır: https://blogs.msdn.microsoft.com/ieinternals/2009 / 09/15 / html5-uygulama sorunları-in-ie8-ve-sonrası /

İşte çalışan örnek: http://www.debugtheweb.com/test/xdm/origin/

Sayfanızda, pop-up ile aynı kökene sahip bir proxy çerçevesi ayarlamanız gerekir. Açılır pencereden proxy çerçevesine bilgileri gönderin window.opener.frames[0]. Ardından proxy çerçevesinden ana sayfaya postMessage'ı kullanın.


1

Bu çözüm, siteyi Yerel Intranet sitelerine değil , Internet Explore'un Güvenilen Sitelerine eklemeyi içerir . Bu çözümü Windows 10 / IE 11.0.10240.16384, Windows 10 / Microsoft Edge 20.10240.16384.0 ve Windows 7 SP1 / IE 10.0.9200.17148'de test ettim. Sayfa Intranet Bölgesine dahil edilmemelidir .

Bu nedenle, Internet Explorer yapılandırmasını açın (Araçlar> İnternet Seçenekleri> Güvenlik> Güvenilen Siteler> Siteler) ve sayfayı ekleyin, burada tüm alt alan adlarını eşleştirmek için * kullanıyorum. Emin sayfa olun değildir Yerel intranet siteleri listelenen (Araçlar> Internet Seçenekleri> Güvenlik> Yerel Intranet> Siteler> Gelişmiş). Tarayıcınızı yeniden başlatın ve tekrar test edin.

Internet Explorer'da güvenilen sitelere ekleyin

In Windows'un 10 / Microsoft Kenar Denetim Masası> Internet Seçenekleri Bu yapılandırmayı bulacaksınız.

GÜNCELLEME

Bu işe yaramazsa, Araçlar> İnternet Seçenekleri> Gelişmiş Ayarlar> Internet Explorer ayarlarını sıfırla ve ardından Sıfırla: içindeki tüm ayarlarınızı sıfırlamayı deneyebilirsiniz : dikkatli kullanın ! Ardından sisteminizi yeniden başlatmanız gerekecek. Bundan sonra siteleri Güvenilen sitelere ekleyin.

Sayfanızın hangi bölgede olduğunu Dosya> Özellikler'de veya sağ tıklamayı kullanarak görün.

İnternet explorer'daki sayfa özellikleri

GÜNCELLEME

Kurumsal bir intranet içindeyim ve bazen çalışıyor ve bazen olmuyor (otomatik yapılandırma? Kurumsal proxy'yi suçlamaya bile başladım). Sonunda bu çözümü kullandım https://stackoverflow.com/a/36630058/2692914 .


0

Bu Q eski, ancak easyXDM bunun için var, html5 .postMessage'ı desteklemeyen bir tarayıcı tespit ettiğinizde bunu olası bir geri dönüş olarak kontrol edin:

https://easyxdm.net/

VBObject sarmalayıcısını ve pencereler veya çerçeveler arasında etki alanı mesajları göndermek için asla uğraşmak zorunda kalmayacağınız her tür şeyi kullanır; burada window.postMessage çeşitli IE sürümleri için başarısız olur (ve edge belki, yine de destekten% 100 emin değil Edge'de var ancak .postMessage için bir geçici çözüme ihtiyaç duyuyor gibi görünüyor)


-3

MessageChannel, bu senaryoda hala bozuk olan postMessage'a dayandığından pencereler / sekmeler arasında IE 9-11 için çalışmaz. "En iyi" çözüm, window.opener (yani window.opener.somefunction ("somedata")) aracılığıyla bir işlevi çağırmaktır.

Burada daha ayrıntılı çözüm bulun


1
Bu, sorudaki ön koşullardan biri olan çapraz başlangıç ​​ayarlarında çalışmaz.
PhistucK
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.