You need to enable JavaScript to run this app. 从postMessage接收的ArrayBuffer无法初始化Uint8Array问题
优惠活动
大模型
产品
解决方案
定价
更多

从postMessage接收的ArrayBuffer无法初始化Uint8Array问题

问题根因

JSON 本身不支持序列化 ArrayBuffer、Uint8Array 这类二进制类型,你在主页面把包含 ArrayBuffer 的数据做 JSON 序列化时,二进制对象会被强制转为普通键值对对象,反序列化后得到的只是和 ArrayBuffer 结构相似的普通 JS 对象,并非原生 ArrayBuffer 实例,自然不支持 slice 等原生方法,也无法用来初始化 Uint8Array。
TypeScript 的类型标注仅为编译期校验,不会改变运行时的实际类型,所以显式类型转换不会生效。


解决方案

方案1(推荐):使用 postMessage 原生结构化克隆能力,跳过 JSON 序列化

postMessage 自带的结构化克隆算法原生支持 ArrayBuffer 等二进制类型传输,同域场景下无需额外序列化处理,性能更好:

  1. 主页面发送逻辑调整:
// 直接传递ArrayBuffer实例,不要做JSON序列化
iframe.contentWindow.postMessage({
  type: 'bufferData',
  buffer: targetArrayBuffer
}, location.origin)
// 如需优化性能还可以转移二进制所有权:
// iframe.contentWindow.postMessage({buffer: targetArrayBuffer}, location.origin, [targetArrayBuffer])
  1. iframe 接收逻辑调整:
window.addEventListener('message', (e) => {
  if (e.origin !== location.origin) return
  if (e.data.type === 'bufferData') {
    // e.data.buffer 就是原生ArrayBuffer实例,可直接使用
    myMessageDataHandler(e.data.buffer)
  }
})

方案2:必须使用JSON序列化时提前做二进制转码

如果业务逻辑要求必须走JSON序列化,可在传输前把二进制转成可序列化的普通数组,接收后再转回ArrayBuffer:

  1. 主页面序列化前处理:
const uint8 = new Uint8Array(targetArrayBuffer)
const serializableStr = JSON.stringify({
  buffer: Array.from(uint8)
})
  1. iframe 反序列化后还原:
const parsedData = JSON.parse(receivedStr)
const uint8 = new Uint8Array(parsedData.buffer)
const realBuffer = uint8.buffer
myMessageDataHandler(realBuffer)

验证方法

你可以在 myMessageDataHandler 中加一行代码确认运行时类型:

console.log(Object.prototype.toString.call(buffer))
// 原生ArrayBuffer会输出 [object ArrayBuffer],如果输出 [object Object] 就是序列化导致的假对象

内容的提问来源于stack exchange,提问作者Rajat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 02:06:03