HTML5如何上传二进制数据_HTML5二进制数据上传法【数据】

最稳妥的二进制文件上传方式是 FormData + fetch/XMLHttpRequest;纯二进制数据则用 ArrayBuffer/Uint8Array/Blob 直接作 body 并设 Content-Type;禁用 base64 传输,避免膨胀与解码错误。

FormData 上传二进制文件最稳妥

绝大多数场景下,直接用 FormData + XMLHttpRequestfetch 是最可靠的方式。它自动处理 Content-Type、边界符(boundary)、编码,且兼容所有现代浏览器。

  • 选中 后,从 files[0] 拿到 BlobFile 对象
  • 新建 FormData,调用 .append("file", file),键名按后端要求填写
  • fetch 不需手动设 Content-Type —— 浏览器会自动生成带 boundarymultipart/form-data
  • 若用 XMLHttpRequest,也**不要**手动设 Content-Type,否则会禁用自动 boundary 生成
const input = document.querySelector('input[type="file"]');
input.addEventListener('change', async () => {
  const file = input.files[0];
  const formData = new FormData();
  formData.append('upload', file); // 键名必须和后端约定一致

  await fetch('/api/upload', {
    method: 'POST',
    body: formData // 不要加 headers: { 'Content-Type': ... }
  });
});

想传纯二进制(非文件)?用 ArrayBuffer + fetchbody

如果数据来自 canvas.toBlob()WebAssembly 内存、或已解析的 ArrayBuffer,不需要走 FormData。这时应显式指定 Content-Type,并把二进制数据作为 body 直接发送。

  • ArrayBufferUint8ArrayBlob 都可直接赋给 fetchbody 选项
  • 务必设置 headers: { 'Content-Type': 'application/octet-stream' } 或其他具体类型(如 image/png
  • 后端收到的是原始字节流,不是 multipart,解析方式完全不同
  • 注意:Safari 对 ArrayBufferbody 的支持从 iOS 16.4 / macOS 13.3 才稳定,旧版本建议转成 Uint8Array
const buffer = new ArrayBuffer(1024);
const view = new Uint8Array(buffer);
// ... 填充数据

await fetch('/api/binary', {
  method: 'POST',
  headers: { 'Content-Type': 'application/octet-stream' },
  body: view // 或 buffer,或 new Blob([buffer])
});

XMLHttpRequest 上传时设 responseType = 'arraybuffer' 是为了接收返回的二进制

上传二进制本身不依赖 responseType,但如果你上传后期待服务器返回一个二进制响应(比如生成的 PDF、压缩包),就必须提前设置 xhr.responseType = 'arraybuffer',否则 xhr.response 会是乱码字符串或 null。

  • 仅影响响应体解析方式,不影响上传过程
  • 设为 'arraybuffer' 后,xhr.responseArrayBuffer;设为 'blob' 则是 Blob
  • 不能设成 'json'''(空字符串)来接收二进制,会强制转字符串导致损坏

常见错误:把 base64 字符串当二进制直接发

有人把图片转成 data:image/png;base64,...,然后试图把它整个塞进 FormDatabody —— 这不是二进制,是文本,体积膨胀约 33%,后端还得额外解码,还容易因 URL 编码或换行符出错。

  • 正确做法:用 fetch(dataUrl) 获取 Blob,或用 atob() + Uint8Array 手动还原(仅限小数据)
  • 更推荐:前端就保持原始 BlobFile,避免无谓的 base64

    编解码
  • 如果后端强制要求 base64,那应在最后一步再编码,且注意去掉 data:...;base64, 前缀
二进制上传的关键不在“怎么发”,而在“发什么”——确认你手里的数据是 BlobArrayBuffer 还是字符串,再选对应路径。很多人卡住,是因为把 FileReader.result 当成二进制用了,其实它默认是字符串。