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错误。
解决步骤
- 修改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)); // 打印后端返回的详细错误信息 };
- 验证后端配置:
- 确保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__')。
- 确保Django模型中
额外调试建议
如果仍报错,查看err.response.data,后端会返回具体的验证错误信息(比如字段类型不匹配、文件大小超限等),便于精准定位问题。
内容的提问来源于stack exchange,提问作者Shahood Amir
相关产品推荐
相关产品推荐

