You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)

验证要点

  1. 查看浏览器Network请求,确认Request Headers的Content-Type为multipart/form-data; boundary=xxxx
  2. Django端request.data['image']应为InMemoryUploadedFile对象,而非字符串
  3. 确保测试用户的status字段值为2(View的create方法中限制了仅激活用户可上传)

内容的提问来源于stack exchange,提问作者Abdulaziz Faxriddinov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 04:50:30