websocket二进制数据处理出错主因是binarytype设错时机、send()传错类型或误将blob.arraybuffer()当同步函数用;必须在onopen中设binarytype="arraybuffer",send前确认类型匹配,blob转arraybuffer需用promise,操作arraybuffer须经typedarray或dataview。

WebSocket前端二进制数据处理出问题,90%是因为binaryType设错时机、send()传错类型、或blob.arrayBuffer()当同步函数用了。
ws.binaryType必须在onopen里第一行设置
连接建立前设ws.binaryType = "arraybuffer"完全无效——浏览器会忽略它。一旦错过这个窗口,onmessage收到的event.data永远是Blob,哪怕你发的是Uint8Array。
- 错误写法:
const ws = new WebSocket(url); ws.binaryType = "arraybuffer";(此时ws.readyState === 0) - 正确写法:
ws.onopen = () => { ws.binaryType = "arraybuffer"; };或ws.addEventListener("open", () => { ws.binaryType = "arraybuffer"; }); - 验证是否生效:
console.log(event.data.constructor.name)—— 必须输出"ArrayBuffer",不是"Blob" - Safari 16+ 会静默丢弃未设
binaryType的大二进制帧,不报错也不触发onerror
send()传ArrayBuffer还是Blob,取决于你要不要字节级操作
传Blob省事、零拷贝、内存友好;传ArrayBuffer或TypedArray才能加协议头、加密、分段、校验。
前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。
- 整文件上传:
ws.send(file)或ws.send(blob)—— 直接传,不额外转 - 自定义协议(如包头4字节+ID+2字节校验):
ws.send(new Uint8Array([...header, ...payload]).buffer) - 禁止传
{type: "data"}这种对象——会被自动JSON.stringify()成字符串,走文本帧 - 若已用
TextEncoder编码字符串,记得取encoder.encode("hello").buffer再发,别漏掉.buffer
Blob转ArrayBuffer必须用promise,不能直接赋值
blob.arrayBuffer()返回的是Promise<arraybuffer></arraybuffer>,不是ArrayBuffer本身。同步流程里直接用它,拿到的是Promise对象,后续所有操作都会失败。
- 错误写法:
const ab = blob.arrayBuffer(); console.log(ab.byteLength);→ 报错Cannot read property 'byteLength' of undefined - 正确写法:
blob.arrayBuffer().then(ab => { /* 解析ab */ }); - 大文件(>32MB)慎用:
arrayBuffer()会把整个Blob加载进内存;应改用blob.slice(start, end).arrayBuffer()分片读 - 旧环境fallback可用
FileReader,但注意reader.result只在load事件后存在,且空Blob可能返回null
ArrayBuffer拼接、下载、base64转码的实用片段
实际项目里常要拼音频帧、下载二进制流、或解析base64响应。这些操作都绕不开Uint8Array中转。
- 拼接多个
ArrayBuffer:new Uint8Array(totalLength).set(new Uint8Array(buf1), offset1);,不能直接concat - 下载
ArrayBuffer:window.URL.createObjectURL(new Blob([ab], {type: "application/octet-stream"})) - base64转
ArrayBuffer:Uint8Array.from(atob(base64), c => c.charCodeAt(0)).buffer(注意atob对非ASCII字符会失败,需先decodeURIComponent(escape())) - 64位long转
ArrayBuffer:必须用DataView写入,别手写位运算——const dv = new DataView(new ArrayBuffer(8)); dv.setBigUint64(0, 1234567890123456789n, true);
最易被忽略的点:ArrayBuffer本身不可读写,所有操作必须通过TypedArray(如Uint8Array)或DataView进行;而new Blob([ab])必须把ArrayBuffer包在数组里,写成new Blob(ab)会静默失败。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










