向FormData追加Blob抛出TypeError: source.on is not a function问题排查
问题:向FormData追加Blob时抛出
TypeError: source.on is not a function 你遇到的问题核心是Node.js环境下的form-data第三方库与浏览器原生FormData的API兼容差异:
- 你参考的MDN文档描述的是浏览器原生
FormData的行为,确实支持Blob类型; - 但你的代码运行在Node.js中,使用的是
form-data第三方库(错误栈里的form-data/lib/form_data.js可证明),这个库的append方法并不直接支持Blob类型,它期望的参数是字符串、Buffer或者Node.js原生的Readable流。
node-fetch提供的blobFromSync生成的Blob是浏览器Blob的模拟实现,并非Node.js原生的流对象,没有流的on事件监听方法,这就是错误source.on is not a function的根源。
解决方案
方案1:将Blob转换为Buffer
把Blob对象转换为Node.js原生的Buffer,即可被form-data正确处理:
const blobFromSync = (...args) => import('node-fetch').then(({ blobFromSync }) => blobFromSync(...args)); let file_location = '/path/to/video/file.mp4'; const file = await blobFromSync(file_location); const chunkSize = 40000; for (let start = 0; start < file.size; start += chunkSize) { const chunk = file.slice(start, start + chunkSize); // 将Blob转换为Buffer const chunkBuffer = Buffer.from(await chunk.arrayBuffer()); const form = new FormData(); form.append('file', chunkBuffer, 'an-id'); // 此处添加发送form数据的逻辑,比如用axios或node-fetch发起请求 }
方案2:直接使用Node.js文件流切片(更高效)
既然处理的是本地文件,直接用Node.js的fs模块创建可读流并指定切片范围,避免Blob转换的额外开销:
const fs = require('fs').promises; let file_location = '/path/to/video/file.mp4'; const chunkSize = 40000; const fileStats = await fs.stat(file_location); const fileSize = fileStats.size; for (let start = 0; start < fileSize; start += chunkSize) { const end = Math.min(start + chunkSize, fileSize); // 创建指定范围的可读文件流 const chunkStream = fs.createReadStream(file_location, { start, end }); const form = new FormData(); form.append('file', chunkStream, 'an-id'); // 此处添加发送form数据的逻辑 }
内容的提问来源于stack exchange,提问作者Devin Dixon
相关产品推荐
相关产品推荐

