93 votes

L'origine croisée de postMessage est-elle brisée dans IE10?

Je suis en train de faire un trivial postMessage exemple de travail...

  • dans IE10
  • entre les fenêtres/onglets (vs iframes)
  • à travers les origines

Supprimer l'une de ces conditions, et les choses fonctionnent bien :-)

Mais aussi loin que je peux dire, entre fenêtre- postMessage seulement semble fonctionner dans IE10 lorsque les deux fenêtres de partager une origine. (Eh bien, en fait -- et bizarrement -- le comportement est légèrement plus permissive que cela: deux origines différentes qui partagent un hôte semblent fonctionner, trop).

Est-ce un bogue documenté? Des solutions de contournement ou d'autres conseils?

(Remarque: Cette question, qui touche à des questions, mais sa réponse est sur IE8 et IE9-pas de 10)


Plus de détails + exemple...

page de lancement de la démo

<!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>

lancement de la page de démonstration

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

Cela fonctionne à: http://jsbin.com/ahuzir/1 -- parce que les deux pages sont hébergées à la même origine (jsbin.com). Mais déplacer la deuxième page n'importe où ailleurs, et il échoue dans IE10.

62voto

ShZ Points 3431

A noter: le lien que vous répondre lié aux états qu' postMessage n'est pas à l'origine de la croix pour des fenêtres séparées dans IE8 et IE9 -- cependant, il a également été écrit en 2009, avant de IE10 est venu autour. Je ne voudrais pas prendre cela comme un signe que c'est corrigé dans IE10.

Comme pour postMessage lui-même, http://caniuse.com/#feat=x-doc-messaging indique notamment qu'il est toujours en panne dans IE10, ce qui semble correspondre à votre démonstration. Le caniuse page de liens vers cet article, qui contient une citation:

Internet Explorer 8+ prend en charge partiellement de la croix-document de messagerie: il travaille actuellement avec des iframe, mais pas de nouvelles fenêtres. Internet Explorer 10, cependant, sera en charge canal de message. Firefox prend actuellement en charge la croix-document de messagerie, mais pas canal de message.

Alors votre meilleur pari est probablement d'avoir un MessageChannel basé codepath, et retourne à l' postMessage si cela n'existe pas. Il ne sera pas vous IE8/IE9 soutien, mais au moins ça marchera avec IE10.

Docs sur MessageChannel: http://msdn.microsoft.com/en-us/library/windows/apps/hh441303.aspx

30voto

LyphTEC Points 71

Créer une page proxy sur le même hôte que le lanceur d'applications. Page Proxy a un iframe avec le jeu de la source à distance page. Cross-origin postMessage va maintenant travailler dans IE10 comme suit:

  • Distance page utilise window.parent.postMessage pour transmettre des données de page proxy. Comme il utilise des iframes, c'est pris en charge par IE10
  • Page Proxy utilise window.opener.postMessage , pour transmettre les données de retour à la page d'écran de lancement. Comme c'est sur le même domaine - il n'y a pas de croix-les problèmes d'origine. Il peut également appeler directement les méthodes globales sur la page de lancement si vous ne souhaitez pas utiliser postMessage - eg. window.opener.someMethod(data)

De l'échantillon (toutes les URLs sont fictitous)

Page de lancement à l' http://somehost.com/launcher.htm

<!DOCTYPE html>
<html>
    <head>
        <title>Test launcher page</title>
        <link rel="stylesheet" href="http://stackoverflow.com/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>

Proxy page d' http://somehost.com/proxy.htm

<!DOCTYPE html>
<html>
    <head>
        <title>Proxy page</title>
        <link rel="stylesheet" href="http://stackoverflow.com/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://someotherhost.org/remote.htm" frameborder="0" height="300" width="500" marginheight="0" marginwidth="0" scrolling="auto"></iframe>

    </body>
</html>

À distance à la page d' http://someotherhost.org/remote.htm

<!DOCTYPE html>
<html>
    <head>
        <title>Remote page</title>
        <link rel="stylesheet" href="http://stackoverflow.com/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>

1voto

Akrikos Points 1235

Droit maintenant, (20014-09-02), Votre meilleur pari est d'utiliser un proxy cadre, comme indiqué dans le msdn post de blog qui détaille une solution de contournement pour ce problème: http://blogs.msdn.com/b/ieinternals/archive/2009/09/16/bugs-in-ie8-support-for-html5-postmessage-sessionstorage-and-localstorage.aspx

Voici l'exemple: http://www.debugtheweb.com/test/xdm/origin/

Vous devez configurer un proxy image sur votre page, qui a la même origine que le popup. Envoyer des informations à partir de la fenêtre contextuelle pour la proxy cadre à l'aide de la fenêtre.ouvre-porte.les frames[0]. Ensuite, utilisez postMessage du proxy de l'image à la page principale.

-3voto

user1337489 Points 34

Canal de message ne fonctionne pas pour IE 9-11 entre les fenêtres/onglets puisqu'il repose sur postMessage, qui est toujours en panne dans ce scénario. La "meilleure" solution de contournement est d'appeler une fonction à travers la fenêtre.ouvre-boîte (ie. de la fenêtre.ouvre-porte.somefunction("somedata") ).

Solution de contournement plus en détail ici

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X