fetch发送arraybuffer需直接传入body并按需设content-type为application/octet-stream等,构造结构化二进制数据用dataview精确写入,禁用json.stringify或tostring,服务端须以原始字节流接收。

用 fetch 发送自定义二进制数据(如 ArrayBuffer)时,关键是正确设置请求体和 Content-Type,并确保数据不被自动转换。默认情况下,fetch 会尝试将 ArrayBuffer 当作字符串处理,导致乱码或失败。
直接传入 ArrayBuffer 作为 body
fetch 原生支持 ArrayBuffer、TypedArray(如 Uint8Array)、Blob 等二进制类型作为 body,无需额外包装或转 base64:
- 直接把
ArrayBuffer传给body选项 - 通常不需要手动设置
Content-Type(除非后端明确要求),因为浏览器不会自动推断二进制类型的 MIME 类型;若需指定,建议用application/octet-stream或具体类型(如image/png) - 务必使用
POST或其它支持 body 的方法
示例:
const buffer = new ArrayBuffer(8);
const view = new Uint8Array(buffer);
view.set([1, 2, 3, 4, 5, 6, 7, 8]);
fetch('/upload', {
method: 'POST',
body: buffer, // ✅ 直接传 ArrayBuffer
headers: {
'Content-Type': 'application/octet-stream' // 可选,按需设置
}
})
.then(res => res.json())
.catch(err => console.error(err));
发送带结构的二进制数据(如自定义协议)
如果你的数据有固定格式(例如包含长度头、魔数、多字段拼接),需手动构造 ArrayBuffer 并填充:
- 用
ArrayBuffer+DataView或TypedArray精确写入字节 - 避免用字符串拼接或
TextEncoder处理纯二进制内容(除非你确实要发 UTF-8 字符) - 注意字节序(
DataView支持显式指定littleEndian)
示例(写入 4 字节整数 + 8 字节浮点数):
const buffer = new ArrayBuffer(12);
const view = new DataView(buffer);
view.setUint32(0, 0x12345678, true); // 小端 32 位整数
view.setFloat64(4, 3.1415926535, true); // 小端 64 位浮点
fetch('/api/process', {
method: 'POST',
body: buffer,
headers: { 'Content-Type': 'application/x-custom-bin' }
});
常见坑与注意事项
-
不要用
JSON.stringify(buffer)—— 它只会输出空对象{},无法序列化 ArrayBuffer -
避免误传
buffer.toString()—— 会变成[object ArrayBuffer]字符串,不是原始字节 -
服务端需按原始字节流接收 —— Node.js(Express)中要用
req.rawBody或body-parser的verify钩子;其他后端也需禁用自动 JSON/表单解析 -
跨域时注意 CORS 预检 —— 自定义
Content-Type(如application/octet-stream)会触发 OPTIONS 预检,后端需正确响应
验证发送是否正确
调试时可在服务端打印前几个字节,或在浏览器开发者工具 Network 面板查看 Request Payload 的十六进制视图(Chrome/Firefox 支持 “Hex” 视图)。也可在 JS 中临时用 console.log(new Uint8Array(buffer)) 检查内容。











