在模式中使用 postMessage 与父级通信 window

using postMessage in a modal to communicate the parent window

我有一个 html 页面,它使用 window.showModalDialog 打开模式,并使用 React 应用程序作为 uri:

var retValue = window.showModalDialog ("http://localhost:8080/myreactapp, "dialogWidth:500px; dialogHeight:500px; dialogLeft:300px;");

这个 React 应用程序显示一个表单,并有一个包含表单值的数据对象。当我提交表格时 我会将更新后的数据对象发送到模态的父 html 页面。

我一直在使用 [postmessage api] (https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) 进行父子之间的交流 windows。

在模态中我有:

window.top.postMessage( message, 'http://localhost:3000/postMessage.html' );

我也试过:

window.parent.postMessage( message, 'http://localhost:3000/postMessage.html' );

我可以在使用 iframe 时从 React 应用程序与父级通信,但在使用模态时不能。

postmessage 在模式中什么都不做,没有错误消息,也没有消息发送。

window.showModalDialog 在大多数浏览器中已被弃用,因此我建议使用库中的模态组件,例如 react-bootstrap 来达到相同的效果。

鉴于此,您可以检查目标的来源 windows 以查看它们是否与您作为目标传入的来源相匹配。如果不匹配,将不会发送消息。

例如

window.top.location.origin 应该匹配 'http://localhost:3000/postMessage.html'

想想看,我从未见过用实际叶页指定来源,所以也许您的目标来源应该是 'http://localhost:3000

我能够让它工作。

在html客户端中我使用了两种测试方法:

 function createWindow()
{
 var win = window.open('http://localhost:8080/myreactapp', 'popup', 
'status=
 no,toolbar=no,location=no,
 directories=no,
 resisable=no,
 srollbars=yes,
 width=1050,height=600');

 }

 function createWindowV2() {
if (window.showModalDialog) {
    showModalDialog ("http://localhost:8080/myreactapp", window, "dialogWidth:1000px; dialogHeight:800px; dialogLeft:300px;");

   }

}

然后在 popup/modal window :

 const [IE, setIE] = useState(false);
 const [chrome, setChrome] = useState(false);
 const [openerWindow, setOpenerWindow] = useState(null);

  useEffect(() => {
   const handler = event => {
    if (typeof event.data !== 'undefined') {
    document.getElementById('received-message').innerHTML = event.data;
    }
    };

   window.addEventListener('message', handler);
   setIE(/*@cc_on!@*/ false || !!document.documentMode);
   setChrome(
  !!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime)
   );

   setOpenerWindow(window.dialogArguments);

   // clean up
   return () => window.removeEventListener('message', handler);
  }, []);


  const handleSubmit = evt => {
    evt.preventDefault();

   if (IE) {
     openerWindow.postMessage(
      message,
     'http://localhost:3000/postMessage.html'
     );
    } else {
         window.opener.postMessage(
         message,
        'http://localhost:3000/postMessage.html' );
    }
   };