Як ви використовуєте window.postMessage між доменами?


88

Здається, сенс window.postMessage полягає у забезпеченні безпечного спілкування між вікнами / фреймами, розміщеними в різних доменах, але насправді це, здається, не дозволяє цього в Chrome.

Ось сценарій:

  1. Вбудуйте <iframe> (з a srcна домен B * ) на сторінку домену A
  2. В кінцевому підсумку <iframe> є в основному тегом <script>, в кінці якого виконується ...
  3. Я викликаю window.postMessage ( some_data , page_on_A )

<iframe>, безумовно, знаходиться в контексті домену B, і я підтвердив, що вбудований javascript у <iframe> виконується належним чином і викликає postMessageправильні значення.

Я отримую таке повідомлення про помилку в Chrome:

Неможливо опублікувати повідомлення для A . Одержувач має походження B .

Ось код, який реєструє прослуховувач подій повідомлень на сторінці в A:

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

Я також намагався зателефонувати window.postMessage(some_data, '*'), але все, що робить, це придушити помилку.

Мені просто не вистачає сутності тут, чи не для цього призначене window.postMessage (...)? Або я просто роблю це жахливо неправильно?

* MIME-тип тексту / html, який він повинен залишатись.


1
Ви, мабуть, це вже знаєте, але MDC має чудовий опис postMessage: developer.mozilla.org/en/DOM/window.postMessage Для реалізації FF очевидно, але, можливо, там є щось, що пояснює, чому це не працює.
Pekka

Відповіді:


79

Ось приклад, який працює на Chrome 5.0.375.125.

Сторінка B (вміст iframe):

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

Зверніть увагу на використання top.postMessageчи parent.postMessageні window.postMessageтут

Сторінка A:

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

А і В мають бути щось на зразок http://domain.com

РЕДАГУВАТИ:

З іншого питання , схоже, домени (A та B тут) повинні мати a /для postMessageправильної роботи.


3
Коли сторінка А перевіряє походження повідомлення, походження НЕ міститиме кінцевого символу '/'. Здається, не має значення, якщо сторінка B вказує кінцевий '/' чи ні. Інше, на що слід звернути увагу, це те, що URL-адреси повинні бути абсолютними URL-адресами.
Catch22,

1
Ця відповідь змусила мене трохи розгубитися і все ще шукати відповіді. blog.teamtreehouse.com/cross-domain-messaging-with-postmessage містить дуже гарне пояснення postMessage. Важливо те, що відправник повідомлення знає домен одержувача. У наведеному вище прикладі A і B не повинні бути однаковими доменами, але B повинен точно знати, який домен використовується А.
Грег Богуміл,

7
Питання про міждоменну. Прийнята відповідь стосується того самого домену.
stackular

@stackular, не зовсім так. A і B може бути будь-яким доменом. Це головна причина наявностіpostMessage
Mic

1
+1. Ми хочемо підтвердити, що це рішення спрацювало у нашій справі. У нас є сторінка, яка містить iframe з іншого домену . Зверніть увагу, що це працює лише в браузері Chrome, оскільки у firefox нам потрібно використовувати window.parent.postMessage замість top . Хоча ми не знаємо, чи можна це застосувати до будь-якого іншого браузера.
rahmatns

24

Ви повинні опублікувати повідомлення від фрейму до батьків, після завантаження.

сценарій кадру:

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

І послухайте це по-батьківськи:

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

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

Для отримання додаткової інформації використовуйте це посилання: http://en.wikipedia.org/wiki/Web_Messaging


2

Можливо, ви намагаєтесь надіслати свої дані з mydomain.com на www.mydomain.com або в зворотному порядку, ПРИМІТКА ви пропустили "www". http://mydomain.com та http://www.mydomain.com - це різні домени для JavaScript.


2
У проекті, який я роблю, я використовую. file:/// Чи можна отримувати помилки домену при витягуванні вмісту виключно з локальної файлової системи?
Jacksonkr
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.