Перенаправить всплывающее окно и сообщение - PullRequest
0 голосов
/ 04 февраля 2019

Я застрял в проблеме, когда мне нужно перенаправить из всплывающего окна в другой домен и отправить ему сообщение.Вот сценарий: -

  1. Пользователь открывает новое всплывающее окно, которое остается в том же домене. (Например: http://doamin_one.com)
  2. Пользователь заполняет форму во всплывающем окне и нажимает кнопку отправитьЭто должно перенаправить окно на http://doamin_two.com, а domain_two.com должен получать данные формы через почтовое сообщение.

Я могу получать сообщения, если я открываю свежее всплывающее окно и делаю сообщение, ноне в случае перенаправления. Вот мой код:

http://domain_one.com -

   function redirect(formData,popup) {
     //popup=window ref object
     popup.location.href="http://domain_two.com"
     popup.postMessage(JSON.stringify(formData),
          "http://domain_two.com");
}

http://domain_two.com -

window.addEventListener("message", receiveMessage, false);
function receiveMessage(event)
{
 if (event.origin !== "http://domain_one.com")
      return;
 let data=event.data;
 //....
}

Ответы [ 2 ]

0 голосов
/ 04 февраля 2019

Одна проблема с кодом в вопросе заключается в том, что .postMessage() вызывается сразу после установки нового .location.href в popup без ожидания события load window в

 popup.location.href="http://domain_two.com"
 popup.postMessage(JSON.stringify(formData),
      "http://domain_two.com");

Для достижения ожидаемого результата вы можете контролировать процесс с оригинального window ('index.html').Каждый window.name имеет уникальное значение.Когда <form> передается в "http://domain_one.com", результирующий FormData может быть преобразован в ArrayBuffer и переведен в index.html, тогда popup (a.html) location.href устанавливается в "http://domain_two.com".При load событии b.html .postMessage() name от window до index.html.Затем FormData передается в .postMessage(), где b.html получает FormData, который был первоначально отправлен в b.html.

(проверки origin, возможно, должны быть скорректированы по приведенному ниже коду. Код был протестирован в plnkr, где имитация междоменного обмена сообщениями не 1: 1, хотя и должна обеспечивать образец для выполнения требования).

index.html (opener)

<!DOCTYPE html>
<html>
<head>
</head>
<body>
  <script>
    // open `popup`
    const popup = window.open('a.html'); 
    // create random values to assign to `name` at `a.html` and `b.html`
    const [firstName, lastName] = [...Array(2)].map(_ => new Uint32Array(16));
    [firstName, lastName].forEach(buffer => window.crypto.getRandomValues(buffer));
    const [decoder, encoder] = [new TextDecoder(), new TextEncoder()];
    const [first, last] = [firstName, lastName].map(buffer => decoder.decode(buffer));
    // set `name` of `popup` (`a.html`) to `first`
    popup.name = first;
    let data;
    window.addEventListener("message", e => {
      // check `name` of `source` 
      if (e.source.name === first) {
        console.log(e.source.name);    
        // store `formData`        
        data = decoder.decode(e.data);
        console.log(e, JSON.parse(decoder.decode(e.data)));
        // set `name` of `popup` to `last`
        popup.name = last;
        // redirect `popup` to `b.html`
        popup.location.href = "b.html";
      }
      // check if `name` of `source` (`b.html`) is `last` 
      if (e.source.name === last) {
        // encode the stored `formData`
        let curr = encoder.encode(data);
        console.log(e.source.name, e.data);
        // transfer `formData` to `b.html`
        e.source.postMessage(curr.buffer, e.source.location.href, [curr.buffer]);
        // data = void 0;
      }
    })
  </script>
</body>
</html>

a.html (popup, "http://domain_one.com")

<!DOCTYPE html>
<html>
<head>
</head>
<body>
  a
  <form>
    <input name="input">
    <input type="submit">
  </form>
  <script>
    document.forms[0].onsubmit = e => {
      // prevent default `form` submission
      e.preventDefault();
      // pass `form` to `FormData` 
      const formData = new FormData(e.target);
      // encode `formData` as a `Uint8Array`
      const encoded = new TextEncoder().encode(JSON.stringify([...formData.entries()]));
      console.log(encoded);
      // transfer `encoded` to `opener` (`index.html`)
      opener.postMessage(encoded.buffer, opener.location.href, [encoded.buffer]);
    }
  </script>
</body>
</html>

b.html (popup, "http://domain_two.com")

<code><!DOCTYPE html>
<html>
<head>
</head>
<body>
  b
  <script>
    const decoder = new TextDecoder();
    let data;
    window.addEventListener("message", receiveMessage, false);

    function receiveMessage(event) {
      // check `origin` of `event`
      if (event.origin !== opener.location.origin)
        return;
      console.log(event);
      // process `formData` from `popup`
      data = JSON.parse(decoder.decode(event.data));
      // do stuff with `formData`
      p.textContent = JSON.stringify(data, null, 2);
    }
    // wait for `load` event to be dispatched before posting message to `opener`
    onload = () => {
      opener.postMessage("ok", opener.location.href);
    }
  </script>
  <pre id="p">

plnkr

0 голосов
/ 04 февраля 2019

Вы можете передать данные формы в "http://domain_two.com", используя параметры строки запроса, а затем проанализировать строку запроса location.href при load событии второго домена

popup.location.href = `http://domain_two.com?${new URLSearchParams(formData.entries()).toString()}`
...