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

React-Django项目中Axios上传图片POST请求返回400错误求助

React-Django Axios POST上传图片返回400错误排查解决

在学习React-Django教程时,尝试通过Axios的POST请求上传图片到Django后端,遇到**AxiosError (Request failed with status code 400)**错误。该请求在Redux的addLead动作中发起,仅上传图片时触发错误;后端可通过Django REST Framework正常添加数据,前端展示、删除数据功能均正常。


相关代码

前端表单组件代码

import React, { Component } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { addLead } from '../../actions/leads';

class Form extends Component {
  
  state = {
    name: '',
    email: '',
    message: '',
    gender: '', 
    image: null, 
  };

  static propTypes = {
    addLead: PropTypes.func.isRequired,
  };

  onChange = (e) => {
    if (e.target.name === 'image') {
      this.setState({ [e.target.name]: e.target.files[0] });
    } else {
      this.setState({ [e.target.name]: e.target.value });
    }
  };
  
  onSubmit = (e) => {
    e.preventDefault();
    const { name, email, message, gender, image } = this.state;
    const lead = { name, email, message, gender, image };

    this.props.addLead(lead);
    this.setState({
      name: '',
      email: '',
      message: '',
      gender: '',
      image: null,
    });

    alert('Form submitted.');
  };

  render(){
    const { name, email, message, gender, image } = this.state;
    return (
      <div className="card card-body mt-4 mb-4">
        <h2>Add Lead</h2>
        <form onSubmit={this.onSubmit} encType="multipart/form-data">
          <div className="form-group">
            <label>Name</label>
            <input
              className="form-control"
              type="text"
              name="name"
              onChange={this.onChange}
              value={name}
              required
            />
          </div>
          <div className="form-group">
            <label>Email</label>
            <input
              className="form-control"
              type="email"
              name="email"
              onChange={this.onChange}
              value={email}
              required
            />
          </div>
          <div className="form-group">
            <label>Message</label>
            <textarea
              className="form-control"
              type="text"
              name="message"
              onChange={this.onChange}
              value={message}
              required
            />
          </div>
          <div className="form-group">
            <label>Gender</label>
            <select
              className="form-control"
              name="gender"
              onChange={this.onChange}
              value={gender}
              required
            >
              <option value="male">Male</option>
              <option value="female">Female</option>
              <option value="other">Other</option>
            </select>
          </div>
          <div className="form-group">
            <label>Image</label>
            <input
              className="form-control"
              type="file"
              name="image"
              onChange={this.onChange}
            />
          </div>
          <div className="form-group">
            <button type="submit" className="btn btn-primary">
              Submit
            </button>
          </div>
        </form>
      </div>
    )
  };
}

export default connect( null, { addLead } )(Form);

Redux addLead动作代码

// ADD LEAD
export const addLead = (lead) => (dispatch) => {
  console.log(lead) 
  axios
  .post('/api/leads/', lead)
  .then((res) => {
      dispatch({
        type: ADD_LEAD,
        payload: res.data,
      });
    })
    .catch((err) => console.log(err));   
};

调试信息

在addLead中打印的lead对象:

{name: 'shuja', email: 'shuja@gmail.com', message: 'Hello Iam shuja', gender: 'male', image: File}

后端正常响应示例(GET请求)

[
    {
        "id": 5,
        "name": "shahood",
        "email": "shahood@gmail.com",
        "message": "hello I am Shahood",
        "gender": "Male",
        "image": "http://127.0.0.1:8000/media/leads_images/2021_03_30_21_01_IMG_5413.JPG",
        "created_at": "2023-08-13T21:09:52.246323Z"
    },
    {
        "id": 6,
        "name": "ahmed",
        "email": "ahmed@gmail.com",
        "message": "hello I am amy",
        "gender": "Male",
        "image": "http://127.0.0.1:8000/media/leads_images/New.png",
        "created_at": "2023-08-13T21:17:35.269783Z"
    }
]

问题原因与解决方法

核心问题

直接将包含File对象的普通JS对象传给Axios,Axios默认会序列化为JSON,但File对象无法被正常序列化,导致请求格式错误;同时上传文件需要multipart/form-data格式,而Axios默认请求头为application/json,与表单的encType不匹配,后端无法解析请求内容,返回400错误。

解决步骤

  1. 修改Redux动作,用FormData封装表单数据,并显式设置请求头:
// ADD LEAD
import axios from 'axios';

export const addLead = (lead) => (dispatch) => {
  const formData = new FormData();
  formData.append('name', lead.name);
  formData.append('email', lead.email);
  formData.append('message', lead.message);
  formData.append('gender', lead.gender);
  if (lead.image) {
    formData.append('image', lead.image);
  }

  axios
  .post('/api/leads/', formData, {
    headers: {
      'Content-Type': 'multipart/form-data'
    }
  })
  .then((res) => {
      dispatch({
        type: ADD_LEAD,
        payload: res.data,
      });
    })
    .catch((err) => console.log(err.response.data)); // 打印后端返回的详细错误信息
};
  1. 验证后端配置:
    • 确保Django模型中image字段为ImageField,并配置了正确的上传路径:
      class Lead(models.Model):
          # ... 其他字段
          image = models.ImageField(upload_to='leads_images/', blank=True, null=True)
      
    • 确保安装了Pillow库(pip install Pillow),用于处理图片文件。
    • DRF序列化器需包含image字段(比如使用fields = '__all__')。

额外调试建议

如果仍报错,查看err.response.data,后端会返回具体的验证错误信息(比如字段类型不匹配、文件大小超限等),便于精准定位问题。

内容的提问来源于stack exchange,提问作者Shahood Amir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 01:52:04