Как я могу делать postMessage через несколько доменов?

Документация для postMessage подразумевает, что обмен сообщениями между доменами возможен. Тем не мение:

// When the popup has fully loaded, if not blocked by a popup blocker

Это не очень четкое примечание о том, как это сделать на самом деле.

Представьте себе два веб-сайта:

  1. [Parent] размещен на qc-a.nfshost.com
  2. [Ребенок] размещен на qc-b.quadhome.com

В родительском:

document.addEventListener('message', function(e) {
  alert('Parent got (from ' + e.origin + '): ' + e.data);

  e.source.postMessage('Round-tripped!', 'http://qc-b.quadhome.com');
}, false);

function go() {
  var w = window.open('http://qc-b.quadhome.com', 'test');

  /* This doesn't work because same-origin policy prevents knowing when
     the opened window is ready. */

  w.postMessage('Vain attempt.', 'http://qc-b.quadhome.com');
}

А у ребенка:

document.addEventListener('message', function(e) {
  alert('Child got (from ' + e.origin + '): ' + e.data);
}, false);

window.opener.postMessage('Ready!', 'http://qc-a.nfshost.com');

Все безрезультатно.

Помощь?


person Scott Robinson    schedule 26.07.2010    source источник


Ответы (2)


В настоящее время я наблюдаю две проблемы. Небольшая ошибка в коде и проблема с тайм-аутом.

1) Ошибка, которую я вижу в вашем коде, заключается в том, что вы используете document.addEventListener. Я думаю, что правильный - window.addEventListener. Это в примере на странице postMessage.

2) С таймаутом вы можете отправить сообщение дочернего окна родителю. Родительское окно затем узнает, когда дочерний элемент будет готов.

person Anh-Kiet Ngo    schedule 26.07.2010
comment
Короче я идиот. Заменил document на window, и готовый обратный вызов работал через window.opener.postMessage. Спасибо! - person Scott Robinson; 26.07.2010

Вы открываете окно и отправляете сообщения друг за другом. Открытый документ не будет готов принять почтовое сообщение. Попробуйте отложить вызов postMessage до завершения загрузки окна.

Очень простой способ проверить это - обернуть w.postMessage () в setTimeout (на 10 секунд) и посмотреть, сможет ли он опубликовать его, когда документ будет готов.

person Ben Rowe    schedule 26.07.2010
comment
Правильно. Комментарий в коде упоминает, что нет способа (насколько я знаю) узнать, когда окно готово. И 10-секундный тайм-аут кажется немного ... хакерским. Обратите внимание, что в дочернем окне я пытаюсь создать сообщение postMessage, указывающее на готовность к открытию. Это тоже не удается. Мысли? - person Scott Robinson; 26.07.2010