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

使用XMLHttpRequest提交请求时Django form.is_valid()返回False如何解决

核心问题原因

你遇到的报错本质是前后端传递数据的格式不匹配:

前端请求的Content-Type为application/json,且发送的是JSON序列化后的字符串;但Django的request.POST对象仅会解析application/x-www-form-urlencoded和multipart/form-data格式的请求载荷,不会自动解析JSON格式的数据,因此表单无法从request.POST中读取到phone字段。


解决方案

以下两种方案任选其一即可:

方案1:修改前端请求格式,适配后端现有逻辑(改动最小)

直接将前端请求改为发送表单编码格式的数据,不需要改动后端视图代码,修改后的JS函数如下:

function sendPhoneVerification(_phone) {
    var http = new XMLHttpRequest();
    // 构造表单格式参数
    const params = `phone=${encodeURIComponent(_phone)}`
    http.open('POST', '/approvephone/', true)
    http.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");
    // 修改Content-Type为表单编码格式
    http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
    // 直接发送表单格式参数,不需要JSON序列化
    http.send(params);
    http.onload = function() {
        alert(http.responseText)
    }
}

方案2:保持前端JSON传参,修改后端解析逻辑

如果你的业务场景需要用JSON格式传参,只需要修改后端视图,先手动解析JSON载荷再传入表单即可:

import json
from django.http import JsonResponse

@csrf_protect
@login_required
def approvephone(request):
    if request.method == 'POST':
        # 先解析请求体中的JSON数据
        try:
            req_data = json.loads(request.body)
        except json.JSONDecodeError:
            return JsonResponse({"code":400,"msg":"请求格式错误"}, status=400)
        # 将解析后的字典传入表单
        form = AddPhoneForm(req_data)
        if form.is_valid():
            # 后续业务逻辑
            # ...

额外注意事项

如果你使用的是django-phonenumber-field提供的PhoneNumberField,需要确保传递的手机号符合你配置的地区格式要求(比如中国手机号需要带+86前缀),否则也可能触发字段校验失败。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 11:09:02