能否通过postMessage向iframe传数据并存储至React Redux?
如何通过postMessage在React父应用与嵌入的iframe子应用间传递数据并存入Redux/组件状态
这个目标完全可以实现,你当前代码无效的核心问题是example1里调用的window.postMessage是向当前页面的window发送消息,而非嵌入的iframe的window对象。以下是修正后的完整方案:
1. 修正example1(父应用)的代码
需要先获取iframe的DOM引用,向iframe的contentWindow发送消息:
import { useRef } from 'react'; function App() { const iframeRef = useRef(null); const sendPostMessage = () => { // 确保iframe已加载且引用有效 if (iframeRef.current?.contentWindow) { // 建议替换*为example2的具体域名,提升安全性 iframeRef.current.contentWindow.postMessage('hello there!', 'http://example2.com'); } }; return ( <div> <button onClick={sendPostMessage}>Click Me</button> <iframe ref={iframeRef} title="iframe example" src="http://example2.com" width="600" height="400" /> </div> ); }
2. 优化example2(iframe子应用)的代码
保留消息监听,但添加来源校验防止恶意消息,同时支持存入组件状态或Redux:
import { useState, useEffect } from 'react'; import { useDispatch } from 'react-redux'; import { saveMessageToRedux } from './path/to/redux-actions'; function App() { const [message, setMessage] = useState("No data"); const dispatch = useDispatch(); useEffect(() => { const handleMessage = (event) => { // 仅接收来自example1的消息,避免跨域风险 if (event.origin !== 'http://example1.com') return; // 存入组件状态 setMessage(event.data); // 存入Redux dispatch(saveMessageToRedux(event.data)); }; window.addEventListener("message", handleMessage); // 组件卸载时清理监听,防止内存泄漏 return () => window.removeEventListener("message", handleMessage); }, [dispatch]); return ( <div> <p>{message}</p> </div> ); }
3. Redux相关示例代码
如果需要存入Redux,先定义对应的action和reducer:
// redux-actions.js export const saveMessageToRedux = (payload) => ({ type: 'SAVE_IFRAME_MESSAGE', payload }); // redux-reducer.js const initialState = ''; export const messageReducer = (state = initialState, action) => { switch(action.type) { case 'SAVE_IFRAME_MESSAGE': return action.payload; default: return state; } };
关键注意事项
- 安全优先:永远不要用
*作为postMessage的目标origin,必须指定具体域名;接收端务必校验event.origin,避免恶意消息攻击 - iframe加载时机:如果需要页面加载时自动发送消息,可监听iframe的
load事件,确保contentWindow已存在 - 复杂数据传递:
postMessage支持传递可序列化的JSON数据,直接发送对象即可(比如postMessage({type: 'USER_DATA', content: userInfo}, origin))
内容的提问来源于stack exchange,提问作者Raymond Yeh
相关产品推荐
相关产品推荐

