Expo React Native中Axios发送含JSON的Multipart请求失败求助
Expo React Native 多部分表单请求(JSON+图片+视频)Android 解决方案
问题定位
Android 环境下使用 Axios 发送包含 JSON、图片、视频的 multipart/form-data 请求时,JSON 字段无法被服务端正确解析。单独发送各部分内容均正常,说明问题出在多部分组合时的字段格式处理上。
可行实现方案
核心思路
不要直接将 JSON 对象放入 FormData,而是把 JSON 序列化为字符串后,作为指定类型的字段加入 FormData;同时确保媒体文件使用 Expo 提供的 URI 直接构建表单字段,无需额外转换为 Blob。
代码实现
import axios from 'axios'; import * as FileSystem from 'expo-file-system'; // 构建多部分表单数据 const buildMultipartForm = async (jsonData, imageUri, videoUri) => { const formData = new FormData(); // 处理JSON数据:序列化为字符串并指定内容类型 formData.append('metadata', JSON.stringify(jsonData), { contentType: 'application/json', }); // 处理图片文件 if (imageUri) { const imageName = imageUri.split('/').pop(); formData.append('image', { uri: imageUri, name: imageName, type: `image/${imageName.split('.').pop()}`, }); } // 处理视频文件 if (videoUri) { const videoName = videoUri.split('/').pop(); formData.append('video', { uri: videoUri, name: videoName, type: `video/${videoName.split('.').pop()}`, }); } return formData; }; // 发送请求 const sendMultipartRequest = async (jsonData, imageUri, videoUri) => { try { const formData = await buildMultipartForm(jsonData, imageUri, videoUri); const response = await axios.post('你的接口地址', formData, { headers: { 'Content-Type': 'multipart/form-data', }, transformRequest: (data, headers) => { // 移除Axios自动添加的全局Content-Type,避免冲突 delete headers.common['Content-Type']; return data; }, }); console.log('请求成功:', response.data); return response.data; } catch (error) { console.error('请求失败:', error.response?.data || error.message); throw error; } };
关键注意事项
- JSON字段处理:必须将JSON序列化为字符串并显式指定
contentType,避免FormData默认将其转为普通文本,导致服务端无法解析。 - 媒体文件URI:Expo中获取的图片/视频URI(如
file://开头)可直接使用,无需额外转Blob,Expo已做兼容处理。 - Content-Type配置:不要手动设置
boundary,Axios会根据FormData自动生成;同时移除Axios默认添加的全局Content-Type头,避免重复设置引发格式错误。 - 字段顺序:部分Android设备对多部分表单的字段顺序敏感,建议将JSON字段放在媒体字段之前。
服务端解析验证
确保服务端将metadata字段按application/json类型解析,而非普通字符串。例如Node.js/Express+multer的处理示例:
const multer = require('multer'); const upload = multer(); app.post('/upload', upload.fields([{name: 'metadata'}, {name: 'image'}, {name: 'video'}]), (req, res) => { const metadata = JSON.parse(req.files.metadata[0].buffer.toString()); const image = req.files.image?.[0]; const video = req.files.video?.[0]; // 后续业务逻辑 });
内容的提问来源于stack exchange,提问作者Alberto Marin
相关产品推荐
相关产品推荐

