跨窗口 iframe 传递数据需显式约定类型并控制序列化:发送端用自定义 replacer 标注 Date、RegExp 等类型,接收端依 $type 字段还原;同域可直传保留原类型;必须校验 origin 和 source 确保安全。

跨窗口 iframe 传递数据时,JavaScript 原生类型(如 string、number、boolean、null、undefined、array、object、Date、RegExp 等)在序列化/反序列化过程中会丢失原始构造信息。例如 Array 变成普通对象,Date 变成字符串,undefined 和函数直接被丢弃。所以“准确识别”不能依赖运行时 typeof 或 instanceof,而要靠**显式约定 + 序列化控制 + 类型标记**。
发送端:主动标注类型,避免隐式转换失真
postMessage 只允许传输可序列化的值(即能被 JSON.stringify 处理的结构),因此必须提前处理不可传类型:
- 用
JSON.stringify+ 自定义 replacer 把Date转为 ISO 字符串,RegExp转为{ $type: 'RegExp', source: '...', flags: '...' } - 对
undefined、function、Symbol等,统一替换为带标识的占位对象,例如{ $type: 'undefined' } - 数组和普通对象都保留原样,但可在顶层加字段说明意图:
{ type: 'user-list', data: [...] } - 避免直接传
new Date()或/abc/g—— 它们过postMessage后就变成"2026-10-08T13:38:00.000Z"或{},无法还原
接收端:按约定解析,不依赖自动类型推断
收到 event.data 后,不能只用 typeof 判断,而应结合结构特征与元字段做判定:
- 检查是否存在
data.$type字段,如data.$type === 'Date'→ 用new Date(data.value)还原 - 遇到
data.$type === 'RegExp'→ 用new RegExp(data.source, data.flags) - 对数组,用
Array.isArray(data)比typeof data === 'object'更可靠(后者对数组也返回"object") - 若消息含
type: 'config'字段,就按配置对象逻辑处理;若含type: 'error',则优先检查data.message和data.stack
同域场景下可补充:用 window 引用绕过序列化
如果父子页面同源(协议、域名、端口全一致),且不需要跨域兼容,可跳过 postMessage,改用直接引用方式保留原始类型:
立即学习“Java免费学习笔记(深入)”;
- 父页调子页方法:
iframe.contentWindow.someFunction({ date: new Date(), regex: /test/ })—— 参数保持原类型 - 子页访问父页变量:
parent.myData(前提是myData已定义且非私有) - 注意:此方式严禁用于跨域 iframe,否则触发
SecurityError
安全通信前提:校验 origin + source 是类型识别的基础保障
类型识别再准确,若消息来源不可信,整个逻辑就失效。必须前置校验:
- 发送方指定明确
targetOrigin,如'https://app.example.com',不用'*' - 接收方严格比对
event.origin(不是event.source.location.origin,后者跨域不可读) - 进一步校验
event.source === iframe.contentWindow,防止其他同源窗口冒充 - 只有通过这两层校验的消息,才进入后续类型解析流程


















