React表单调用DRF接口发邮件出现400错误,寻求排查方案
问题:React调用API返回400错误,API页面测试正常
我尝试通过以下API发送表单数据:React应用调用时返回400错误,但直接在API接口页面测试能正常运行。对比请求负载发现React应用没带CSRF Token,但之前用模型序列化器时不需要这个Token。怀疑问题出在序列化器,但找不到具体原因,请问400错误可能是什么原因?
sendEmail.js
const testmessage = "This is a test message" const testemail = "dsfds@dsfg.de" const clientnametest = "name" function sendProposal(values) { console.log("start sending proposal..."); setSendProp(true) const data = new FormData() data.append("Clientname", clientnametest || ""); data.append("Sender", testemail || ""); data.append("Message", testmessage || ""); axios.post(API.email.proposal, data, { headers: { "Authorization": `Bearer ${accessToken}`, 'Accept' : 'application/json', }, withCredentials: true, }) .then(res => {}) .finally(() => { setSendProp(false) }) success() }
views.py
class ProposalEmailView(APIView): permission_classes = [IsAuthenticated] serializer_class = ProposalEmailSerializer def post(self, request, *args, **kwargs): serializer_class = ProposalEmailSerializer(data=request.data) if serializer_class.is_valid(): data = serializer_class.validated_data ClientName = data.get('ClientName') Sender = data.get('Sender') Message = data.get('Message') send_mail('Contact Form mail from ' + ClientName, Message, Sender, ['test@test.test'],) return Response({"success": "Sent"}, status=status.HTTP_200_OK) return Response({"error": "Failed"}, status=status.HTTP_400_BAD_REQUEST)
serializers.py
class ProposalEmailSerializer(serializers.Serializer): ClientName = serializers.CharField() Sender = serializers.EmailField() Message = serializers.CharField()
可能的原因及解决方法
1. 字段名大小写不匹配
React代码中用data.append("Clientname", ...),但序列化器定义的字段是ClientName(第二个字母N大写),字段名大小写完全不一致会导致序列化器验证失败,直接返回400错误。这是最核心的问题——API页面测试时你可能手动输入了正确的字段名,而React代码里写错了。
2. 序列化器未返回具体错误信息
当前视图中验证失败仅返回{"error": "Failed"},无法看到具体错误细节。建议修改视图,返回序列化器的错误详情,快速定位问题:
return Response(serializer_class.errors, status=status.HTTP_400_BAD_REQUEST)
3. CSRF Token问题(次要排查项)
虽然使用了Bearer Token认证,但Django默认对表单提交会检查CSRF Token。如果后端未配置CSRF_COOKIE_HTTPONLY = False,需要手动获取CSRF Token并添加到请求头:
// 获取CSRF Token function getCookie(name) { let cookieValue = null; if (document.cookie && document.cookie !== '') { const cookies = document.cookie.split(';'); for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].trim(); if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } const csrftoken = getCookie('csrftoken'); // 在axios请求头中添加 headers: { "Authorization": `Bearer ${accessToken}`, 'Accept' : 'application/json', 'X-CSRFToken': csrftoken },
4. FormData格式兼容性(低概率)
axios发送FormData时会自动设置Content-Type: multipart/form-data,但可以在浏览器开发者工具中检查请求头是否正确,确保Django能正常解析FormData数据。
内容的提问来源于stack exchange,提问作者Matthias
相关产品推荐
相关产品推荐

