记录:用window.open打开的页面如何进行数据交互?

场景: 在一个新增物资的页面上,我要点击按钮,执行 window.open()打开人员录入的工单。在人员工单上,我要填写完信息,点击提交按钮,就会产生一个人员申请的id出来。在提交完以后,我想要这个人员申请的id传到新增物资的页面上来。

解决方案:

使用 window.open() 打开新页面,这意味创建了一个完全独立的浏览器窗口/标签页,与原页面是两个独立的文档环境。

这两个页面的通信方式如下:

方案一:使用 postMessage API(推荐)

这是跨窗口通信的标准方式:

javascript 复制代码
javascript
// 在原页面打开新窗口时
const newWindow = window.open(`/page/tickets/visitor/new`, '_blank');
// 监听来自新窗口的消息
window.addEventListener('message', (event) => {
  // 验证消息来源(安全考虑)
  if (event.origin !== window.location.origin) return;
  
  if (event.data.type === 'PERSON_CREATED') {
    const { id } = event.data.payload;
    // 更新页面上的 ID 显示
    setId(id);
  }
});

// 在新页面提交成功后
// window.opener 指向打开当前窗口的窗口
window.opener.postMessage({
  type: 'PERSON_CREATED',
  payload: { id: newPersonId }
}, window.location.origin);

// 关闭当前窗口
window.close();

方案二:使用 localStorage + 轮询(适用于不能修改新页面的情况)

javascript 复制代码
javascript
// 在原页面中
const newWindow = window.open(`/page/tickets/visitor/new`, '_blank');

// 轮询检查 localStorage 中是否有新创建的 ID
const checkForNewId = setInterval(() => {
  const newPersonData = localStorage.getItem('newPersonCreated');
  if (newPersonData) {
    const { id } = JSON.parse(newPersonData);
    setId(id);
    localStorage.removeItem('newPersonCreated');
    clearInterval(checkForNewId);
  }
}, 1000);

// 在新页面提交成功后
localStorage.setItem('newPersonCreated', JSON.stringify({ id: newPersonId }));
window.close();

方案三:URL 参数传递 + 页面刷新监听

javascript 复制代码
javascript
// 在原页面中
const newWindow = window.open(`/page/tickets/visitor/new`, '_blank');

// 监听新窗口关闭事件
const checkWindowClosed = setInterval(() => {
  if (newWindow.closed) {
    // 检查是否创建了新人员
    const newPersonId = sessionStorage.getItem('newPersonId');
    if (newPersonId) {
      setId(newPersonId);
      sessionStorage.removeItem('newPersonId');
    }
    clearInterval(checkWindowClosed);
  }
}, 500);

// 在新页面提交成功后
sessionStorage.setItem('newPersonId', newPersonId);
window.close();

对于跨窗口通信场景,我最推荐使用方案一(postMessage API) ,因为:

  1. 它是现代浏览器提供的标准跨窗口通信方式
  2. 安全性更好(可以验证消息来源)
  3. 实时性更强(不需要轮询)
  4. 符合 Web API 的最佳实践

根据你项目的情况和安全要求,选择最适合的方案即可。

相关推荐
米米商聊1 天前
同名附件为什么被 Map 覆盖?重复键与一对多索引
前端·javascript
echome8881 天前
Python 异常处理:try、else、finally 的正确搭配
开发语言·前端·python·异常处理·编程技巧
时间的情敌1 天前
OpenLayers 实战|Vue3 + OpenLayers 完整工程案例(加载天地图、要素、弹窗、绘制、WFS)
前端·openlayers
陈随易1 天前
下载神器!Motrix 停更三年后重写回归
前端·后端·程序员
前端的日常1 天前
一个人+AI做情侣食谱小程序,0 费用的服务器
前端·后端
计算机魔术师1 天前
谷歌搜索广告踩刹车,AI广告成为救命稻草
前端
总要学点什么1 天前
第81篇:数据可视化-PM2.5分布——让圆点的胖瘦替每座城市报出浓度
前端·信息可视化·echarts·cesium·空间分析
IT_陈寒1 天前
Vue的v-for里用了个临时变量,页面直接挂了
前端·人工智能·后端
hunter_0761 天前
一次 iOS 真机签名 409 的完整排查:证书、设备、描述文件为什么总是"对不上"
前端
枣把儿1 天前
开源!公众号排版+一键发布工具懒人版
前端