如何通过axios以二进制形式发送文件 解决上传文件损坏问题
问题原因
你当前代码的核心问题是请求格式和Postman的binary模式不匹配:
- Postman选择binary上传时,会直接把文件的原始二进制内容作为整个请求体发送,没有任何额外包装
- 你用
FormData封装文件发送的是multipart/form-data格式请求,请求里会自动插入multipart分隔符、字段描述头,后端接收到的内容包含大量非文件本身的冗余信息,自然会出现文件损坏。
修复方案
完全去掉FormData相关逻辑,直接把文件的二进制内容/可读流作为请求体发送即可,和Postman的行为保持一致。
小文件版本(直接读Buffer)
适合体积不大的视频文件,实现简单:
const fs = require('fs/promises'); const path = require('path'); const axios = require('axios'); const pickFrom = path.join(__dirname, '../sampleVideos', path.basename(filename)); // 直接读取文件原始二进制内容,不做表单包装 const fileBuffer = await fs.readFile(pickFrom); const url = `${domain}/api/video/upload/${videometa._id}`; const config = { headers: { // 通用二进制流类型,若后端有指定类型可替换,比如video/mp4 'Content-Type': 'application/octet-stream', 'Content-Length': fileBuffer.length }, maxBodyLength: Infinity }; // 记得加await,你原代码漏了await会拿不到正确响应 const response = await axios.post(url, fileBuffer, config);
大文件版本(流式上传)
如果文件体积大,不想把整个文件加载到内存,可以直接传文件可读流,axios会自动处理分块传输:
const fs = require('fs'); const path = require('path'); const axios = require('axios'); const pickFrom = path.join(__dirname, '../sampleVideos', path.basename(filename)); // 直接创建文件可读流,不放入FormData const fileStream = fs.createReadStream(pickFrom); const url = `${domain}/api/video/upload/${videometa._id}`; const config = { headers: { 'Content-Type': 'application/octet-stream' // 流式上传无需手动计算content-length,axios会自动设置Transfer-Encoding: chunked }, maxBodyLength: Infinity }; const response = await axios.post(url, fileStream, config);
注意事项
- 不要携带任何
multipart/form-data相关的请求头,不要用FormData包装文件 - 如果后端校验Content-Type,替换为接口要求的MIME类型即可,比如mp4文件可设为
video/mp4 - 原代码中
axios.post前缺少await,如果是在async函数中调用记得补上,否则无法正确获取响应、捕获异常。
内容的提问来源于stack exchange,提问作者Anish
相关产品推荐
相关产品推荐

