在模式中使用 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' );
}
};
我有一个 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' );
}
};