如何使用window.postmessage与parent进行交流window
How to use window.postmessage to communicate with parent window
我正在创建一个 React 应用程序,我希望我的用户将其嵌入到他们的网站上。此应用程序将显示在两个 iframe 中,但我想一次只显示一个 iframe。因此,应用程序的一部分将是一个简单的按钮,第二部分将是一个表单,一旦用户决定使用该应用程序(它是一个聊天应用程序)就会弹出。
我设置了一个非常简单的组件来显示按钮,以便它可以向 parent 网站发送消息。我不确定自己做错了什么,但是当发送 window.postmessage 事件时,我收到错误消息:
Uncaught DOMException: Blocked a frame with origin "http://localhost:3002" from accessing a cross-origin frame.
这里是示例parent网站代码:
<h1>Hello! This is some static content</h1>
<iframe src="http://localhost:3002"
style="width: 108px; height: 50px; padding: 0px; margin: 10px 20px; position: fixed; bottom: 0px; right: 0px; overflow: visible; opacity: 1; border: 0px; z-index: 999998; transition-duration: 250ms; transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1); transition-property: opacity, top, bottom;"
id="dbhchat"></iframe>
<h3>Thanks for checking out my blog!</h3>
<script>
window.addEventListener('message', event => {
// IMPORTANT: check the origin of the data!
if (event.origin.startsWith('http://localhost:3002')) {
// The data was sent from your site.
// Data sent with postMessage is stored in event.data:
console.log(event.data);
} else {
// The data was NOT sent from your site!
// Be careful! Do not use it. This else branch is
// here just for clarity, you usually shouldn't need it.
return;
}
});
</script>
我的组件将消息发送到 parent window:
import React from 'react';
import { IconButton } from '@material-ui/core';
import PhotoCamera from '@material-ui/icons/PhotoCamera';
import './App.css';
function App() {
const send = () => {
if (window && window.parent) {
console.log('we have message sending here', window.parent);
window.parent.postMessage('message', 'http://localhost:3002', false);
}
}
return (
<div className="App">
<header style={{ background: 'red' }} className="App-header">
<IconButton onClick={send} color="primary" aria-label="upload picture" component="span">
<PhotoCamera />
</IconButton>
</header>
</div>
);
}
export default App;
在此先感谢您帮助解决这个问题!
我发现了一个有点奇怪的问题解决方案。我真的不知道为什么会这样,但只是将 e.preventDefault()
添加到 react 发送函数之后就可以正常工作了。
const send = (e) => {
e.preventDefault();
if (window && window.parent) {
window.parent.postMessage({message: 'The message is being set up here', hide: 'dbhchat', show: 'dbhchat'}, '*');
}
}
添加之后,一切正常。如果有人能提供更多详细信息,说明为什么会这样,那就太好了!
我正在创建一个 React 应用程序,我希望我的用户将其嵌入到他们的网站上。此应用程序将显示在两个 iframe 中,但我想一次只显示一个 iframe。因此,应用程序的一部分将是一个简单的按钮,第二部分将是一个表单,一旦用户决定使用该应用程序(它是一个聊天应用程序)就会弹出。
我设置了一个非常简单的组件来显示按钮,以便它可以向 parent 网站发送消息。我不确定自己做错了什么,但是当发送 window.postmessage 事件时,我收到错误消息:
Uncaught DOMException: Blocked a frame with origin "http://localhost:3002" from accessing a cross-origin frame.
这里是示例parent网站代码:
<h1>Hello! This is some static content</h1>
<iframe src="http://localhost:3002"
style="width: 108px; height: 50px; padding: 0px; margin: 10px 20px; position: fixed; bottom: 0px; right: 0px; overflow: visible; opacity: 1; border: 0px; z-index: 999998; transition-duration: 250ms; transition-timing-function: cubic-bezier(0.645, 0.045, 0.355, 1); transition-property: opacity, top, bottom;"
id="dbhchat"></iframe>
<h3>Thanks for checking out my blog!</h3>
<script>
window.addEventListener('message', event => {
// IMPORTANT: check the origin of the data!
if (event.origin.startsWith('http://localhost:3002')) {
// The data was sent from your site.
// Data sent with postMessage is stored in event.data:
console.log(event.data);
} else {
// The data was NOT sent from your site!
// Be careful! Do not use it. This else branch is
// here just for clarity, you usually shouldn't need it.
return;
}
});
</script>
我的组件将消息发送到 parent window:
import React from 'react';
import { IconButton } from '@material-ui/core';
import PhotoCamera from '@material-ui/icons/PhotoCamera';
import './App.css';
function App() {
const send = () => {
if (window && window.parent) {
console.log('we have message sending here', window.parent);
window.parent.postMessage('message', 'http://localhost:3002', false);
}
}
return (
<div className="App">
<header style={{ background: 'red' }} className="App-header">
<IconButton onClick={send} color="primary" aria-label="upload picture" component="span">
<PhotoCamera />
</IconButton>
</header>
</div>
);
}
export default App;
在此先感谢您帮助解决这个问题!
我发现了一个有点奇怪的问题解决方案。我真的不知道为什么会这样,但只是将 e.preventDefault()
添加到 react 发送函数之后就可以正常工作了。
const send = (e) => {
e.preventDefault();
if (window && window.parent) {
window.parent.postMessage({message: 'The message is being set up here', hide: 'dbhchat', show: 'dbhchat'}, '*');
}
}
添加之后,一切正常。如果有人能提供更多详细信息,说明为什么会这样,那就太好了!