WebSocket二进制传输需严格匹配binaryType设置时机、发送类型与接收处理:open后立即设ws.binaryType="arraybuffer",send传Blob或ArrayBuffer依需求而定,Blob转ArrayBuffer须用blob.arrayBuffer()异步处理,new Blob必须传数组包裹ArrayBuffer。

WebSocket传输二进制数据时,ArrayBuffer和Blob不是“选哪个更好”,而是“用错场景会卡死、变慢或收不到数据”。关键在连接初始化、发送路径、接收处理三处是否匹配。
设置ws.binaryType = "arraybuffer"必须在open之后立即执行
不设或设晚了,onmessage收到的event.data就是Blob,哪怕你发的是Uint8Array。这不是 bug,是规范行为。
- 错误写法:
const ws = new WebSocket(url); ws.binaryType = "arraybuffer";—— 连接还没建好,设置被忽略 - 正确时机:在
ws.onopen回调里第一行就设,或监听open事件后立刻赋值 - 验证方式:打印
event.data.constructor.name,应为"ArrayBuffer";若为"Blob",说明设置未生效 - 注意 Safari 16+ 对未设
binaryType的 WebSocket,在接收大二进制帧时可能静默丢弃(无报错)
ws.send()传Blob还是ArrayBuffer取决于你是否需要字节级操作
直接ws.send(file)最省事,但无法加协议头、无法加密、无法分段控制;想做这些,就必须走ArrayBuffer路径。
- 传
Blob(含File):适合整文件上传,浏览器零拷贝,内存友好,Chrome/Firefox 支持稳定 - 传
ArrayBuffer或TypedArray(如Uint8Array):适合自定义二进制协议,比如前4字节存消息ID、后2字节存校验码 - 禁止传普通对象或字符串——
ws.send({type: 'data'})会自动转成字符串,不是二进制 - 若已用
TextEncoder编码字符串,记得用encoder.encode('hello').buffer取ArrayBuffer再发
Blob.arrayBuffer()是异步的,别在同步流程里等它
当你收到Blob(比如没设binaryType,或后端发来的是Blob),想转成ArrayBuffer做解析,不能用FileReader手动绕一圈——除非你需要进度事件。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 现代写法(推荐):
blob.arrayBuffer().then(ab => { /* 处理ab */ }),简洁且 Promise 可链式处理 - 旧环境 fallback:
FileReader仍可用,但要注意reader.result只在load后存在,readAsArrayBuffer不会抛错但可能返回null(比如 blob 为空) - 大文件风险:调用
arrayBuffer()会把整个Blob加载进内存,32MB以上建议分片读取(用blob.slice()+ 多次arrayBuffer()) - 别写
const ab = blob.arrayBuffer()然后直接用ab——它是个 Promise,不是 ArrayBuffer
new Blob([arrayBuffer])必须用数组包裹ArrayBuffer
这是最容易拼错的语法点。漏掉中括号,new Blob(arrayBuffer)会报错或创建空 Blob。
- 正确:
new Blob([ab])、new Blob([uint8Arr.buffer])、new Blob([ab1, ab2])(合并多个缓冲区) - 错误:
new Blob(ab)→ TypeError: Failed to construct 'Blob' - 生成 Blob URL 预览时:
URL.createObjectURL(new Blob([ab], {type: 'image/png'})),type选项影响下载后缀和 MIME 解析 - 注意:
Blob是不可变的,修改内容必须新建实例;而ArrayBuffer内容可通过TypedArray视图随时改写
真正麻烦的从来不是转换本身,而是混合使用时的状态错位:比如前端设了binaryType = "arraybuffer",后端却按Blob逻辑拼包;或者用arrayBuffer()读大文件时没加 loading 状态,UI 直接卡住。这些点不写日志、不测弱网、不看内存快照,上线后才暴露。










