重定向弹出窗口并发布消息 [英] Redirect a Popup and Post Message

查看:82
本文介绍了重定向弹出窗口并发布消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我陷入了一个问题,即我必须从弹出窗口重定向到另一个域并向其发布消息. 这是场景:-

I am stuck in a problem where i have to redirect from a popup window to a different domain and post a message to it. Here is the scenario :-

  1. 用户打开一个位于相同域中的新弹出窗口.(例如: http://doamin_one.com )
  2. 用户在弹出窗口中填写表格,然后单击提交".这应该将窗口重定向到 http://doamin_two.com ,domain_two.com应该通过发布消息接收表单数据. /li>
  1. User opens a new popup window which stays in same domain.(ex: http://doamin_one.com)
  2. User fills the form in the popup window and clicks submit. This should redirect the window to http://doamin_two.com and domain_two.com should receive form data via post message.

如果我打开新的弹出窗口并发布消息,但能够接收消息,但在重定向的情况下却不能.这是我的代码:

I am able to receive messages if i open fresh popup and do post message but not in the case of redirection. Here is my code:

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

推荐答案

问题代码的一个问题是,在popup上设置了新的.location.href之后,无需等待.postMessage() > window at

One issue with the code at the question is that .postMessage() is called immediately following setting a new .location.href at popup without waiting for the load event of window at

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

要获得预期的结果,您可以从原始的window('index.html')控制过程.每个window.name都设置为唯一值.当在"http://domain_one.com"提交<form>时,可以将生成的FormData转换为ArrayBuffer并传输到index.html,然后将popup(a.html)location.href设置为"http://domain_two.com".在b.html .postMessage()load事件中,windowindex.htmlname.然后,将FormData传递给.postMessage(),其中b.html获取最初在b.html提交的FormData.

To achieve the expected result you can control the process from the original window ('index.html'). Each window.name is set to a unique value. When the <form> is submitted at "http://domain_one.com" the resulting FormData can be converted to an ArrayBuffer and transferred to index.html, then popup (a.html) location.href is set to "http://domain_two.com". At load event of b.html .postMessage() the name of the window to index.html. Then the FormData is passed to .postMessage() where b.html gets the FormData that was originally submitted at b.html.

(origin检查可能需要在下面的代码中进行调整.该代码已在plnkr上进行了测试,在该代码中,跨域消息传递的模拟不是1:1,尽管应该提供一种如何实现要求的模式).

(The origin checks might need to be adjusted at the below code. The code was tested at plnkr, where simulation of cross-domain messaging is not 1:1, though should provide a pattern for how to accomplish the requirement).

index.html(opener)

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

<!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"></pre>
</body>
</html>

plnkr

这篇关于重定向弹出窗口并发布消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆