如何用Axios从React向DRF正确发送嵌套Multipart/Form-Data?
解决React通过Axios向DRF发送Multipart/Form-Data的问题
核心错误点
- FormData追加方式错误:直接追加对象会被转成
[object Object]字符串,FormData仅支持字符串、Blob或File类型。 - Axios参数位置错误:你把FormData放在了
params(URL查询参数)里,应该放在data(请求体)中。 - 图片数据类型错误:
taskImages中存储的是文件路径字符串,而非实际的File对象,无法被DRF解析为上传文件。 - 手动设置Content-Type:手动指定
multipart/form-data会丢失自动生成的边界标识(boundary),导致DRF无法正确解析表单数据。
正确实现步骤
1. 在React中获取并维护File对象
确保从文件选择框中拿到实际的File对象,而非路径:
const [taskImages, setTaskImages] = useState([]); // 处理文件选择 const handleFileSelect = (e) => { const selectedFiles = Array.from(e.target.files); // 直接存储File对象,或包装为符合序列化器结构的对象 setTaskImages(selectedFiles); }; // 对应HTML <input type="file" multiple onChange={handleFileSelect} />
2. 正确构建FormData
DRF对嵌套数组的FormData格式要求是images[索引][字段名],按此规则追加数据:
const formData = new FormData(); // 追加文本字段 formData.append('text', e.target.text.value); // 追加图片数组 taskImages.forEach((file, index) => { // 对应序列化器中images数组下的image字段 formData.append(`images[${index}][image]`, file); });
3. 发送Axios请求
不要手动设置Content-Type,Axios会自动根据FormData生成带边界的正确头:
axios.post('/api/your-task-endpoint/', formData, { baseURL: baseURL, // 若需认证,添加Authorization头(示例) // headers: { 'Authorization': `Bearer ${yourToken}` } }) .then(res => console.log('提交成功:', res.data)) .catch(err => console.error('提交失败:', err));
4. DRF视图配置(可选但必要)
确保视图类配置了MultiPartParser以支持文件上传:
from rest_framework.parsers import MultiPartParser, FormParser from rest_framework.generics import CreateAPIView from .serializers import TaskSerializer class TaskCreateView(CreateAPIView): serializer_class = TaskSerializer parser_classes = (MultiPartParser, FormParser) # 其他视图配置(权限、查询集等)
验证DRF接收格式
调整后,DRF的request.data会符合预期:
<QueryDict: {'text': ['Its my test task'], 'images': [{'image': [<InMemoryUploadedFile: 1.jpg (image/jpeg)>]}, {'image': [<InMemoryUploadedFile: 2.jpg (image/jpeg)>]}]}>
内容的提问来源于stack exchange,提问作者Anna Berezko
相关产品推荐
相关产品推荐

