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

Django与JavaScript交互出现400 Bad Request错误排查求助

Django POST请求400 Bad Request 问题排查与修复

核心错误点

  1. request.is_ajax()已被弃用:Django 3.1及以上版本移除了该方法,此判断会直接返回False,触发400响应。
  2. 未导入json模块:视图中使用json.loads()但未导入对应库,会引发未捕获异常。
  3. CSRF Token可能未正确渲染:若JS代码在独立文件中,模板标签{{ csrf_token }}不会被解析,导致CSRF验证失败。
  4. 请求合法性验证不足:缺少对Content-Type的校验,无法确保接收的是合法JSON请求。

修复代码

1. 修正Django视图

import json
from django.http import JsonResponse

def email_view(request):
    # 替换is_ajax(),验证请求方法与Content-Type
    if request.method == 'POST' and request.content_type == 'application/json':
        try:
            info = json.loads(request.body)

            companyName = info.get('companyName')
            userName = info.get('userName')
            fullName = info.get('fullName')
            email = info.get('email')
            expireDate = info.get('dateFormatted')
            version = info.get('version')
            code = info.get('code')
            
            print("##########", companyName)
            print("##########", userName)
            print("##########", fullName)
            print("##########", email)
            print("##########", expireDate)
            print("##########", version)
            print("##########", code)

            return JsonResponse({'message': 'Data received correctly.'})
        except json.JSONDecodeError:
            # 处理JSON解析失败场景
            return JsonResponse({'message': 'Invalid JSON data.'}, status=400)

    return JsonResponse({'message': 'No valid request.'}, status=400)

2. 修正JavaScript(确保CSRF Token有效)

若JS代码在Django模板中:

<script>
    var DateTime = luxon.DateTime;
    // 直接从模板渲染CSRF Token
    const csrfToken = '{{ csrf_token }}';

    const sendBtns = [...document.getElementsByClassName("send_btn")]
    sendBtns.forEach(btn => btn.addEventListener('click', () => {
        const companyName = btn.getAttribute("company-name")
        const userName = btn.getAttribute("user-name")
        const fullName = btn.getAttribute("full-name")
        const email = btn.getAttribute("email")
        const expireDate = btn.getAttribute("expire-date")
        const version = btn.getAttribute("version")
        const code = btn.getAttribute("code")

        function formatDate(inputDate) {
            const dt = lux填亚提示词范围。 '" layingiwong.com@ Kim zone.不对,原代码保留:
            const dt = luxon.DateTime.fromISO(inputDate);

            if (dt.isValid) {
                const day = dt.toFormat('dd');
                const monthName = dt.toFormat('LLL');
                const year = dt.toFormat('yyyy');
                return day + '-' + monthName + '-' + year;
            }

            return inputDate;
        }

        const dateFormatted = formatDate(expireDate);

        const info = {
            companyName,
            userName,
            fullName,
            email,
            dateFormatted,
            version,
            code,
        };
        console.log(info)
        fetch('/user_send_info/', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-CSRFToken': csrfToken, 
            },
            body: JSON.stringify(info),
        })
        .then(response => response.json())
        .then(info => {
            console.log('Response from Django:', info);
        })
        .catch(error => {
            console.error('Error to send AJAX request:', error);
        });
    }));
</script>

若JS代码在独立文件中(通用CSRF Token获取):

// 从cookie中读取CSRF Token
function getCsrfToken() {
    let cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        const cookies = document.cookie.split(';');
        for (let cookie of cookies) {
            cookie = cookie.trim();
            if (cookie.startsWith('csrftoken=')) {
                cookieValue = decodeURIComponent(cookie.substring(10));
                break;
            }
        }
    }
    return cookieValue;
}

// 后续fetch请求中使用
fetch('/user_send_info/', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'X-CSRFToken': getCsrfToken(), 
    },
    body: JSON.stringify(info),
})
// 其余代码保持不变

3. 确认URL配置

你的URL配置path("user_send_info/", email.email_view, name='email_view')与fetch请求路径/user_send_info/一致,无需修改。确保Django的APPEND_SLASH设置为True(默认开启),可自动处理末尾斜杠不一致的情况。


排查技巧

打开浏览器开发者工具(F12)→ Network标签:

  • 检查请求头X-CSRFToken是否存在且有有效值
  • 查看请求体是否为合法JSON格式
  • 查看响应体中的具体错误信息,Django的400响应会返回明确提示(如CSRF verification failed或JSON parse error),可快速定位问题。

内容的提问来源于stack exchange,提问作者Angel Gabriel Chable Concepcio

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 17:44:54