React+Axios上传图片至Django API时文件为空的问题求助
解决React + Axios上传图片到Django API时File字段为空的问题
我一眼就揪出了问题的核心:你现在是用JSON格式提交文件数据,但File对象属于二进制类型,JSON根本没法正确序列化它,所以控制台里file字段才会显示为{},再加上请求头设置的Content-Type: application/json完全不适合文件上传场景,这俩问题凑一起就导致图片传不出去了。下面给你一步步捋清楚解决方案:
1. 先修复State更新的小bug
看你的onChange和handleImage方法里,更新state时写的是this.setState({ cats, });,但你的state字段明明是car_photo啊!这会导致你的分类和文件数据根本没存到正确的state位置,先把这两处改成:
await this.setState({ car_photo: cats });
2. 改用FormData构造上传数据
文件上传必须用FormData对象,它是专门用来处理multipart/form-data格式请求体的。修改你的handleSubmit方法:
handleSubmit(e) { e.preventDefault(); // 创建FormData实例 const formData = new FormData(); // 循环把每个图片项的字段加到FormData里 this.state.car_photo.forEach((photo, index) => { formData.append(`car_photo[${index}][category]`, photo.category); formData.append(`car_photo[${index}][sub_category]`, photo.sub_category); // 只有当file存在时才添加,避免传空值 if (photo.file) { formData.append(`car_photo[${index}][file]`, photo.file); } }); axios({ method: "PUT", url: `${config.apiUrl.car}${this.props.match.params.pk}/profile/`, headers: { Accept: "application/json, application/xml, text/plain, text/html, *.*", // 删掉Content-Type: application/json,让Axios自动处理multipart/form-data Authorization: "Bearer " + JSON.parse(authToken), }, data: formData, // 这里传FormData而不是普通JSON }) .then((res) => { Swal.fire({ title: "Car", type: "success", text: "Car Update Successfully !", showConfirmButton: false, timer: 2000, }); }) .catch((err) => { Swal.fire({ title: "Car", type: "error", text: "Error while updating new Car!", timer: 2000, }); }); }
3. Django端的注意事项
因为你用的是PUT请求,Django默认中间件可能不会自动解析PUT请求里的multipart/form-data数据。如果你的视图里拿不到request.FILES,可以试试这两种办法:
- 业务允许的话改用
PATCH请求,Django对PATCH的multipart数据处理更友好 - 或者在视图里手动适配PUT请求的multipart解析:
from django.http import QueryDict def your_car_profile_view(request, pk): if request.method == 'PUT': # 手动解析multipart数据 if request.content_type.startswith('multipart/form-data'): # 直接使用request.POST和request.FILES即可 form_data = request.POST files = request.FILES # 后续处理你的业务逻辑...
为什么之前的方式不行?
- JSON只能序列化字符串、数字、普通对象这类基本类型,File对象是二进制资源,无法被JSON序列化,所以你console.log(data)看到的file是
{},这是File对象转JSON后的默认结果 - 上传文件必须用
multipart/form-data格式的请求体,而不是application/json,两者的编码规则完全不同,硬套肯定传不出去
按照上面的步骤修改后,应该就能正常把图片和分类数据一起传到Django API了。
内容的提问来源于stack exchange,提问作者Piotr
相关产品推荐
相关产品推荐

