后台点「详情」弹出一个新窗口,新窗口需要知道当前行的 id。很多人第一反应是把 id 存到全局变量,结果子页面读不到。因为 window.open 打开的是独立文档,父页面的变量它看不见,只能靠 URL、sessionStorage 或 postMessage 传。
最常用:参数拼在 URL 上
var url = 'detail.html?id=' + encodeURIComponent(id) + '&type=order';
window.open(url, '_blank', 'width=1000,height=700');
// 子页面
var p = new URLSearchParams(location.search);
var id = p.get('id');中文和特殊符号一定要 encodeURIComponent,否则 &、# 会把参数截断。
参数多或含对象:用 sessionStorage
URL 上拼太长的 JSON 既不安全也不好看。同源的两个窗口可以共享 sessionStorage,先写再开:
sessionStorage.setItem('detailArgs', JSON.stringify({ id: id, from: 'list' }));
window.open('detail.html');
// 子页面
var args = JSON.parse(sessionStorage.getItem('detailArgs') || '{}');注意同源限制,用完记得 removeItem,不然下次还是旧数据。
子页面回调父页面
同源时子页面可以直接操作 opener,保存成功后刷新列表并关窗:
window.opener.location.reload();
window.close();但设置了 noopener 之后 opener 就是 null。确实需要双向通信时用 postMessage 更稳,接收时校验 event.origin。window.name 也能传参且不受同源限制,但容易被覆盖,不推荐。
几个实际的坑
- 被拦截:window.open 必须在点击的同步流程里调用,放在 setTimeout 或 ajax 回调里会被当弹窗拦掉。
- 参数没编码:搜索词里带 & 或空格,子页面拿到的是残缺值。
- 跨域取不到:不同域名读不了 location.search,老实走 URL 拼接。
原则很简单:少量参数走 URL,复杂结构走 sessionStorage,双向通信走 postMessage。