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

使用Post方法通过Ajax向Django视图发送数据却无法获取的问题

问题诊断与解决方案

你遇到的核心问题是发送的数据格式和请求头不匹配:你设置了Content-type为表单提交的application/x-www-form-urlencoded,但实际发送的是JSON字符串,这两种格式不兼容,导致Django的request.POST根本读不到你传的name和price。

下面给你两种可行的修复方案,选一种适合你的就行:

方案一:保持表单格式发送(更贴合Django默认的表单处理)

把Ajax里的JSON数据转成表单格式的键值对字符串,这样request.POST就能正常解析了:

修改你的home.html中的JS代码:

<script>
document.getElementById('postForm').addEventListener('submit',postName);
function postName(e){
    e.preventDefault();
    var name = document.getElementById('id_name').value;
    var price = document.getElementById('id_price').value;
    // 转成表单格式的字符串,用encodeURIComponent处理特殊字符
    var formData = `name=${encodeURIComponent(name)}&price=${encodeURIComponent(price)}`;
    
    var xhr = new XMLHttpRequest();
    xhr.open('POST',"{% url 'ajax-home' %}",true);
    xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
    xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");
    
    xhr.onload = function(){
        console.log('数据已成功提交');
        // 这里可以根据后端返回的响应做后续操作,比如刷新产品列表
    }
    xhr.send(formData);
}
</script>

后端的views.py可以不用改,或者优化成用表单验证(更规范):

def ajax_home(request):
    if request.method == 'POST':
        form = ProductForm(request.POST)
        if form.is_valid():
            # 直接用表单保存,不用手动创建Product实例
            form.save()
        # 即使表单无效,也可以在这里处理错误
    else:
        form = ProductForm()
    products = Product.objects.all()
    context = {
        'form':form,
        'products': products
    }
    return render(request, 'myapp/home.html', context)

方案二:改用JSON格式发送数据

如果你更倾向于用JSON传递数据,需要修改请求头并在后端解析JSON:

修改home.html的JS代码:

<script>
document.getElementById('postForm').addEventListener('submit',postName);
function postName(e){
    e.preventDefault();
    var name = document.getElementById('id_name').value;
    var price = document.getElementById('id_price').value;
    var data = {
        'name':name,
        'price':price,
    }
    
    var xhr = new XMLHttpRequest();
    xhr.open('POST',"{% url 'ajax-home' %}",true);
    // 把请求头改成JSON格式
    xhr.setRequestHeader('Content-type','application/json');
    xhr.setRequestHeader("X-CSRFToken", "{{ csrf_token }}");
    var myData= JSON.stringify(data);
    
    xhr.onload = function(){
        console.log('JSON数据已发送:', myData);
    }
    xhr.send(myData);
}
</script>

对应的views.py需要解析request.body里的JSON:

import json
from django.http import JsonResponse

def ajax_home(request):
    if request.method == 'POST':
        # 从请求体读取并解析JSON
        try:
            data = json.loads(request.body)
            name = data.get('name', "still not found")
            # 用前端传的price,而不是固定的100
            price = data.get('price', 100)
            p = Product(name=name, price=price)
            p.save()
            # 可选:返回JSON响应告诉前端提交成功
            # return JsonResponse({'status': 'success', 'message': '产品已添加'})
        except json.JSONDecodeError:
            # 处理JSON解析失败的情况
            pass
    else:
        form = ProductForm()
    products = Product.objects.all()
    context = {
        'form':form,
        'products': products
    }
    return render(request, 'myapp/home.html', context)

额外提醒

  • 用encodeURIComponent处理参数值(方案一),可以避免空格、特殊字符导致的解析错误
  • 如果你用Django的表单,优先用方案一的表单处理方式,能自动帮你做数据验证和清洗,减少bug
  • 测试的时候可以在后端打印request.POST(方案一)或者request.body(方案二),确认数据是否正确接收

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 17:32:28