Axios@1.6.7 POST请求无法向Django后端发送FormData问题
问题:React Axios发送FormData到Django REST后端返回400错误
在React前端使用axios@1.6.7向Django REST后端发送包含title和pdf_file的FormData,发送前打印FormData内容正常,但后端返回400 Bad Request。用Postman发送相同请求却能成功,对比发现两者的Content-Length差异极大。项目中其他非FormData的Axios请求均正常。
前端发送代码(SendForm.js)
const formDataToSend = new FormData(); formDataToSend.append('title', formData.title); formDataToSend.append('pdf_file', formData.pdf_file); console.log(formDataToSend.get('title'), formDataToSend.get('pdf_file')) const config = { headers: { 'Content-Type': 'multipart/form-data', 'X-CSRFToken': Cookies.get('csrftoken') }, } const response = await axios.post(`${process.env.REACT_APP_API_URL}/api/posts/create-post/`, formDataToSend, config );
后端错误日志
Bad Request: /api/posts/create-post/ [02/Mar/2024 19:15:46] "POST /api/posts/create-post/ HTTP/1.1" 400 28
异常Axios请求头
POST /api/posts/create-post/ HTTP/1.1 Accept: application/json, text/plain, */* Accept-Encoding: gzip, deflate, br, zstd Accept-Language: en-US,en;q=0.9 Connection: keep-alive Content-Length: 280 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryZWvOJOP8DWxLqAIC Cookie: csrftoken=KpiB3K4gLN4gT3GsnPLfP9eBpOcwJ1Sb; sessionid=hgq77mclr8rynznly95gx40vjaj07cor Host: localhost:8000 Origin: http://localhost:3000 Referer: http://localhost:3000/ Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: same-site User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 X-CSRFTOKEN: KpiB3K4gLN4gT3GsnPLfP9eBpOcwJ1Sb sec-ch-ua: "Chromium";v="122", "Not(A:Brand";v="24", "Google Chrome";v="122" sec-ch-ua-mobile: ?0 sec-ch-ua-platform: "Windows"
正常Postman请求头
Content-Type: multipart/form-data; boundary=--------------------------998229612431930001760561 X-CSRFToken: E5khHlkBQgTXXhWhosEKtX2LOx1o8z2s User-Agent: PostmanRuntime/7.36.3 Accept: */* Postman-Token: c5e3e2f7-aaeb-4a16-a4da-d6f0e99e691b Host: 127.0.0.1:8000 Accept-Encoding: gzip, deflate, br Connection: keep-alive Cookie: csrftoken=E5khHlkBQgTXXhWhosEKtX2LOx1o8z2s; sessionid=yvwjf72zx1ymw78uxb4p10dli5pu1wxo Content-Length: 560891
Axios全局配置
import axios from 'axios'; axios.defaults.xsrfHeaderName = "X-CSRFTOKEN"; axios.defaults.xsrfCookieName = "csrftoken"; axios.defaults.withCredentials = true; axios.defaults.credentials = 'same-origin'; axios.defaults.withXSRFToken = true export default axios;
解决方案
问题核心是手动设置了Content-Type: multipart/form-data。Axios在发送FormData时会自动生成包含正确boundary的Content-Type头,手动设置会导致boundary不匹配,后端无法正确解析表单数据,进而导致文件没有被实际发送(从Content-Length的巨大差异也能看出)。
修改步骤:
- 删除请求配置中手动设置的Content-Type:
const config = { headers: { // 移除该行:'Content-Type': 'multipart/form-data', 'X-CSRFToken': Cookies.get('csrftoken') }, }
- 额外检查:确认
formData.pdf_file是真实的File对象(比如从<input type="file">的files[0]获取),如果是字符串或其他类型,FormData无法正确处理文件内容。 - 可选优化:由于Axios全局配置已经设置了CSRF相关参数,可以直接移除config中的
X-CSRFToken,让Axios自动处理CSRF令牌。
内容的提问来源于stack exchange,提问作者Caden The Yak
相关产品推荐
相关产品推荐

