使用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
相关产品推荐
相关产品推荐

