the sure sent make intended from example domain cross contentwindow child being html5 cross-browser compatibility internet-explorer-10 postmessage

html5 - sure - postmessage iframe javascript



¿Se rompe el postMessage de origen cruzado en IE10? (7)

Estoy tratando de hacer que postMessage ejemplo de postMessage trivial ...

  • en IE10
  • entre ventanas / pestañas (vs. iframes)
  • a través de orígenes

Elimine cualquiera de estas condiciones, y las cosas funcionan bien :-)

Pero, por lo que puedo decir, entre-ventana postMessage solo parece funcionar en IE10 cuando ambas ventanas comparten un origen. (Bueno, de hecho, y extrañamente, el comportamiento es un poco más permisivo que eso: dos orígenes diferentes que comparten un host parecen funcionar también).

¿Es esto un error documentado? ¿Alguna solución provisional u otro consejo?

(Nota: esta pregunta toca los problemas, pero su respuesta es sobre IE8 e IE9, no 10)

Más detalles + ejemplo ...

demo página del lanzador

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

demo página lanzada

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

Esto funciona en: demo - porque ambas páginas están alojadas en el mismo origen (jsbin.com). Pero mueva la segunda página a cualquier otro lado, y falla en IE10.


Basándome en la respuesta por enredo, tuve éxito en IE11 [y emulé el modo IE10] usando el siguiente fragmento:

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

Luego pude comunicarme usando la típica pila postMessage, estoy usando un mensajero estático global en mi escenario (aunque no creo que sea significativo, también estoy adjuntando mi clase de mensajería)

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; } }

No importa cuánto lo intenté, no pude hacer que las cosas funcionen en IE9 e IE8

Mi configuración donde está funcionando:
Versión de IE: 11.0.10240.16590, Versiones de actualización: 11.0.25 (KB3100773)


Basándose en las respuestas de LyphTEC y Akrikos, otra solución es crear un <iframe> dentro de una ventana emergente en blanco, lo que evita la necesidad de una página de proxy separada, ya que la ventana emergente en blanco tiene el mismo origen que su abrelatas.

Página del iniciador en 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>

Página remota en 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>

No estoy seguro de cuán frágil es esto, pero está funcionando en IE 11 y Firefox 40.0.3.


Cree una página de proxy en el mismo host que el iniciador. La página de proxy tiene un iframe con fuente configurada en página remota. Cross-origin postMessage ahora funcionará en IE10 así:

  • La página remota usa window.parent.postMessage para pasar datos a la página de proxy. Como esto usa iframes, es compatible con IE10
  • La página proxy usa window.opener.postMessage para pasar los datos a la página del iniciador. Como está en el mismo dominio, no hay problemas de origen cruzado. También puede invocar directamente métodos globales en la página del iniciador si no desea utilizar postMessage, por ej. window.opener.someMethod(data)

Muestra (todas las URL son ficticias)

Página del iniciador en 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>

Página de proxy en 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>

Página remota en 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>


En este momento, (2014-09-02), su mejor opción es usar un marco de proxy como se indica en la publicación de blog de msdn que detalla una solución para este problema: https://blogs.msdn.microsoft.com/ieinternals/2009/09/15/html5-implementation-issues-in-ie8-and-later/

Aquí está el ejemplo de trabajo: debugtheweb.com/test/xdm/origin

Debe configurar un marco proxy en su página que tenga el mismo origen que el elemento emergente. Envíe información de la ventana emergente al marco proxy utilizando window.opener.frames[0] . Luego use postMessage desde el marco del proxy a la página principal.


Esta solución implica agregar el sitio a los Sitios de Confianza de Internet Explore y no en los sitios de la Intranet Local. Probé esta solución en Windows 10 / IE 11.0.10240.16384, Windows 10 / Microsoft Edge 20.10240.16384.0 y Windows 7 SP1 / IE 10.0.9200.17148. La página no debe estar incluida en la Zona de Intranet .

Abra la configuración de Internet Explorer (Herramientas> Opciones de Internet> Seguridad> Sitios de confianza> Sitios) y agregue la página, aquí uso * para que coincida con todos los subdominios. Asegúrese de que la página no esté en la lista en los sitios Intranet locales (Herramientas> Opciones de Internet> Seguridad> Intranet local> Sitios> Avanzado). Reinicia tu navegador y prueba de nuevo.

En Windows 10 / Microsoft Edge , encontrará esta configuración en el Panel de control> Opciones de Internet.

ACTUALIZAR

Si esto no funciona, puede intentar restablecer todos sus ajustes en Herramientas> Opciones de Internet> Configuración avanzada> Restablecer configuración de Internet Explorer y luego Restablecer: ¡ úselo con precaución ! Entonces necesitarás reiniciar tu sistema. Después de eso, agrega los sitios a los sitios de confianza.

Consulte en qué zona está su página en Archivo> Propiedades o haciendo clic con el botón derecho.

ACTUALIZAR

Estoy en una intranet corporativa y, a veces, funciona y otras no (configuración automática, incluso comencé a culpar al proxy corporativo). Al final usé esta solución https://.com/a/36630058/2692914 .


MessageChannel no funciona para IE 9-11 entre ventanas / pestañas ya que depende de postMessage, que aún está roto en este escenario. La "mejor" solución es llamar a una función a través de window.opener (es decir, window.opener.somefunction ("somedata")).

blogs.msdn.com/b/ieinternals/archive/2009/09/16/…


Estaba equivocado cuando originalmente publiqué esta respuesta: en realidad no funciona en IE10. Aparentemente, la gente lo ha encontrado útil por otras razones, así que lo dejo para la posteridad. Respuesta original a continuación:

Vale la pena señalar: el enlace en esa respuesta que vinculó a estados indica que postMessage no tiene un origen cruzado para las ventanas separadas en IE8 e IE9, sin embargo, también se escribió en 2009, antes de que llegara IE10. Entonces no tomaría eso como una indicación de que está arreglado en IE10.

En cuanto a postMessage sí mismo, http://caniuse.com/#feat=x-doc-messaging indica que todavía está roto en IE10, que parece coincidir con su demo. La página caniuse enlaces a este artículo , que contiene una cita muy relevante:

Internet Explorer 8+ admite parcialmente la mensajería cruzada de documentos: actualmente funciona con iframes, pero no con ventanas nuevas. Internet Explorer 10, sin embargo, admitirá MessageChannel. Firefox actualmente admite mensajes cruzados, pero no MessageChannel.

Entonces su mejor opción es tener una ruta de código basada en MessageChannel , y una alternativa a postMessage si eso no existe. No obtendrá soporte para IE8 / IE9, pero al menos funcionará con IE10.

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