如何通过Axios发送包含Blob的嵌套Multipart/FormData?
如何正确生成嵌套Multipart/FormData并通过Axios发送?
我完全懂你现在的头疼——想要构建一个符合特定嵌套结构的FormData,不管是用第三方包还是手动append都没得到预期结果,尤其是media数组里的url和文件对象要么混在一起,要么直接变成[Object Object]。别慌,我给你两个靠谱的解决方案:
方案一:手动构建FormData(最可控)
手动构建虽然麻烦一点,但完全能按照你的预期生成结构,不会有第三方包的配置坑。核心思路是把嵌套结构拆成FormData能识别的键值对,数组元素用media[索引][字段名]的格式来命名键:
// 你的原始对象 const obj = { table: 'food', id: this.food.id, media: [ {url: "https://picsum.photos/400/400"}, {image: new Blob(['test'], {type: 'image/png'})}, // 替换成你的Blob/File对象 {url: "https://picsum.photos/200/400"} ] }; // 创建空的FormData实例 const formData = new FormData(); // 先添加简单的非嵌套字段 formData.append('table', obj.table); formData.append('id', obj.id); // 遍历media数组,逐个处理每个元素 obj.media.forEach((item, index) => { // 如果当前元素有url字段,用media[索引][url]作为键 if (item.url) { formData.append(`media[${index}][url]`, item.url); } // 如果当前元素有image文件,用media[索引][image]作为键 if (item.image) { // 第三个参数可设置文件名,后端能拿到这个名称,可选但推荐 formData.append(`media[${index}][image]`, item.image, 'custom-filename.png'); } }); // 用Axios发送请求,记得设置正确的Content-Type axios.post('/your-api-endpoint', formData, { headers: { 'Content-Type': 'multipart/form-data' } });
这样生成的FormData结构完全符合你的预期:每个media数组元素都是独立的,url和image分别在对应的索引位置里。
方案二:正确配置object-to-formdata包
如果你还是想用这个第三方包,问题出在默认配置上——默认情况下它不会显式添加数组索引,导致多个media元素的字段被合并了。只需要开启indices: true选项,就能让数组索引显式出现在键名里:
import objectToFormData from 'object-to-formdata'; const obj = { table: 'food', id: this.food.id, media: [ {url: "https://picsum.photos/400/400"}, {image: new Blob(['test'], {type: 'image/png'})}, {url: "https://picsum.photos/200/400"} ] }; // 关键是设置indices: true,其他选项按需调整 const formData = objectToFormData(obj, { indices: true, // 强制生成带索引的键,比如media[0][url]、media[1][image] nullsAsUndefineds: false, booleansAsIntegers: false }); // 发送请求和上面一致 axios.post('/your-api-endpoint', formData, { headers: { 'Content-Type': 'multipart/form-data' } });
为什么直接append对象不行?
你之前尝试的media.append('media[]', {url: "xxx"})会变成[Object Object],是因为FormData只能接收字符串、Blob或File类型的数据。直接传对象的话,会自动调用对象的toString()方法,结果就是[Object Object],所以必须把对象拆成具体的键值对来append。
内容的提问来源于stack exchange,提问作者Philipp Mochine
相关产品推荐
相关产品推荐

