React上传图片至Django后端报错:提交数据非文件,求技术支持
问题解决:React前端向Django后端上传图片报错
核心错误原因
报错提示"The submitted data was not a file. Check the encoding type on the form"的本质问题:
- React端使用
JSON.stringify和Content-Type: application/json提交数据,无法传输File对象 - 文件上传必须用
FormData格式,且不能手动设置Content-Type(浏览器会自动生成带boundary的multipart/form-data头) - Django View中冗余的
post方法会覆盖ModelViewSet默认逻辑,还存在拼写错误
分步修改方案
1. 修复React API请求代码(关键)
将InsertArticle方法改为用FormData封装数据,移除错误的Content-Type设置:
static InsertArticle(body, token) { const formData = new FormData(); // 逐个添加表单字段,文件对象直接append formData.append('tour_title', body.tour_title); if (body.image) { formData.append('image', body.image); } formData.append('country', body.country); formData.append('price', body.price); formData.append('duration', body.duration); formData.append('description', body.description); return fetch('http://127.0.0.1:8000/api/articles/', { method:'POST', headers: { 'Authorization':`Token ${token}` // 不要手动设置Content-Type,浏览器会自动处理 }, body: formData }).then(resp => resp.json()) .then((data) => { if (!data.payload && data.error) { alert(data.error); throw "Error"; } else { return data.payload; } }) .catch(err => { console.log(err) }); }
2. 修正React Form组件的图片预览逻辑
File对象无法直接作为img的src,改用URL.createObjectURL生成预览地址:
// 在组件顶部添加预览状态 const [imagePreview, setImagePreview] = useState(""); // 修改图片输入框的onChange事件 <input type="file" className="form-control" name="image" id="image" accept="image/*" onChange={(e) => { const file = e.target.files[0]; setImage(file); // 生成预览URL setImagePreview(URL.createObjectURL(file)); }} /> // 替换原预览图片代码 <br/> {imagePreview && <img src={imagePreview} width="100px"/>} <br/>
同时移除无效的file={image}属性,React的文件输入框不支持该属性控制。
3. 清理Django View冗余代码
删除ArticleViewSet中的post方法:
# 以下代码完全冗余,且存在拼写错误(Article.object.create → Article.objects.create),直接删除 def post(self, request, *args, **kwargs): image = request.data['image'] tour_title = request.data['tour_title'] Article.object.create(tour_title=tour_title, image=image) return HttpResponse({'message': 'Image added'}, status=200)
ModelViewSet已经自带create方法,自定义post会覆盖默认逻辑导致冲突。
4. 确认Django基础配置
- 安装图片处理依赖:
pip install pillow - 在
settings.py中配置媒体文件路径:
MEDIA_URL = '/media/' MEDIA_ROOT = BASE_DIR / 'media'
- 在项目根
urls.py中添加媒体文件路由:
from django.conf import settings from django.conf.urls.static import static urlpatterns = [ # 现有路由 ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
验证要点
- 查看浏览器Network请求,确认Request Headers的
Content-Type为multipart/form-data; boundary=xxxx - Django端
request.data['image']应为InMemoryUploadedFile对象,而非字符串 - 确保测试用户的
status字段值为2(View的create方法中限制了仅激活用户可上传)
内容的提问来源于stack exchange,提问作者Abdulaziz Faxriddinov
相关产品推荐
相关产品推荐

