使用Axios携带FormData时出现source.on is not a function错误求助
解决Axios上传FormData时出现
source.on is not a function错误 问题描述
执行Axios POST请求上传FormData时触发source.on is not a function错误,相同功能使用request包可正常运行,切换到Axios后出现该问题。
错误原因分析
- Axios请求参数格式错误:将FormData包裹在
{ data: formData }中传递,不符合Axios的参数要求,应该直接将FormData作为POST请求的第二个参数。 - 文件添加方式不兼容:向FormData添加文件时使用了request包支持的对象格式,Axios(Node.js环境)不兼容该格式,需要调整文件传递方式。
修复步骤
1. 修正Axios POST请求的参数传递
原错误代码:
const res = await axios.post( clientPayload?.uploadLink, { data: formData }, { headers: { 'content-type': 'multipart/form-data', }, } );
修复后:
const res = await axios.post( clientPayload?.uploadLink, formData, { headers: formData.getHeaders() // 利用form-data包自带方法生成正确请求头 } );
说明:Node.js环境下的
form-data包提供了getHeaders()方法,会自动生成包含boundary的Content-Type头,手动设置反而会导致头信息不匹配引发错误。
2. 修正FormData添加文件的方式
原错误代码:
formData.append('file', { filepath: fs.createReadStream(file.path), filename: file.path, contentType: null, });
修复后:
const fileStream = fs.createReadStream(file.path); formData.append('file', fileStream, { filename: path.basename(file.path), // 建议仅传递文件名而非完整路径 contentType: 'video/mp4' // 根据实际视频类型设置,如video/mov等 });
说明:Axios在Node.js环境中需要直接传递文件流对象,结合
form-data包的选项参数指定文件名和类型。
完整修复后的代码
import axios from 'axios'; import fs from 'fs'; import path from 'path'; import FormData from 'form-data'; // 确保已安装form-data包 export const uploadVideo = async (title: string, file: any) => { const formData = new FormData(); try { const response = await axios.put( `https://url.com/api/videos`, {}, { params: { title, }, headers: { Authorization: `Apisecret ${process.env.VIDEO_SECRET}`, Accept: 'application/json', 'Content-Type': 'application/json', }, } ); const data = response?.data; const clientPayload = data?.clientPayload; formData.append('policy', clientPayload?.policy); formData.append('key', clientPayload?.key); formData.append('x-amz-signature', clientPayload['x-amz-signature']); formData.append('x-amz-algorithm', clientPayload['x-amz-algorithm']); formData.append('x-amz-date', clientPayload['x-amz-date']); formData.append('x-amz-credential', clientPayload['x-amz-credential']); formData.append('success_action_status', '201'); formData.append('success_action_redirect', ''); // 修正文件添加逻辑 const fileStream = fs.createReadStream(file.path); formData.append('file', fileStream, { filename: path.basename(file.path), contentType: 'video/mp4' }); // 修正Axios请求配置 const res = await axios.post( clientPayload?.uploadLink, formData, { headers: formData.getHeaders() } ); return res; } catch (error) { if (axios.isAxiosError(error)) { logger.error('error message: ', error); } else { logger.error('unexpected error: ', error); } } };
额外注意事项
- 确保已安装
form-data包:执行npm install form-data或yarn add form-data完成安装。 - 文件的
contentType需根据实际视频格式调整,若不确定可留空,由form-data包自动检测。
内容的提问来源于stack exchange,提问作者Ali Benromdhane
相关产品推荐
相关产品推荐

