跨域场景下从当前标签页向新开标签页传递数据问题咨询
问题原因分析
postMessage参数缺失:跨域场景下postMessage方法的第二个参数targetOrigin为必填项,你当前调用时没有传入该参数,默认会限制仅同域下发送消息,跨域请求直接被浏览器拦截。- 消息发送时机错误:
window.open执行后,新标签页的页面资源加载、事件监听注册都需要时间,你在调用open后立刻发送消息,此时接收端的message监听器还没完成注册,消息自然无法被捕获。 - 接收端语法错误:你提供的监听代码中,事件回调的函数语法有误,箭头函数缺少
=>标识符,会导致代码报错无法执行,监听器本身就没有成功注册。
正确实现方案
postMessage方案本身是支持跨域窗口传值的,修正后的实现代码如下:
发送端(初始页面按钮点击逻辑)
const targetOrigin = 'http://localhost:7000'; // 明确指定新窗口的目标域名 const windowObjectReference = window.open(`${targetOrigin}/elmo/experiment`); // 监听新窗口加载完成后再发送消息 windowObjectReference.addEventListener('load', () => { // 第二个参数传入目标域名,限制消息仅发送到指定域名的窗口 windowObjectReference.postMessage('message data', targetOrigin); }, false);
接收端(新开页面逻辑)
window.addEventListener('message', (e) => { // 必须校验消息来源,防止恶意站点发送伪造消息 if (e.origin !== 'http://你初始页面的实际域名') return; console.log('*********************** data', e.data); }, false);
如果存在特殊场景不适合用postMessage,也可以选择备选方案:
- 小体积非敏感数据可以直接拼接在新开页面的URL参数中,接收端通过
location.search解析获取 - 如果需要传递大体积或敏感数据,可先由初始页面把数据上传到公共后端服务,生成临时唯一标识拼接在URL中,新页面加载完成后用该标识从后端拉取对应数据
内容的提问来源于stack exchange,提问作者Lakhan Jain
相关产品推荐
相关产品推荐

