jquery $.ajax post请求方式传递json对象django后台接收异常(&连接类似get url参数)

1.问题提出

在使用django开发web项目时,发现一个错误,在使用jquery 进行ajax操作,前台使用post方式提交json对象,后台接收到的数据一种类似get传参的数据。

前端代码:

$.ajax({
         url:"/foxbot/setRun/",
         data:{"param":true,"a":123},
         type:'post',
         success:function (res) {

         }
       });

后台效果(debug):

在图中我们可以看到,接受到的并不是json形式的数据,也不是json字符串,所以将导致后面的json.loads(params)转换失败。这个现象一开始没注意,因为在postman中测试是没有问题的,如下图,后面再前台用jquery ajax时就报错

 2.问题分析

       经过查找资料,最终发现是前台ajax json参数没用配置contentType: 'application/json'  以及json对象没有使用JSON.stringify进行序列化转换。但是这就又有一个疑问了:为什么不能直接传递json对象参数而用序列化成json字符串让后台去接收?

查阅jquey文档(https://api.jquery.com/jQuery.ajax/)中解释:

data

Type: PlainObject or String or Array

Data to be sent to the server. It is converted to a query string, if not already a string. It's appended to the url for GET-requests. See processData option to prevent this automatic processing. Object must be Key/Value pairs. If value is an Array, jQuery serializes multiple values with same key based on the value of the traditional setting (described below).

翻译:

要发送到服务器的数据。如果不是字符串,它将转换为查询字符串。它被附加到get请求的url中。请参阅processdata选项以阻止此自动处理。对象必须是键/值对。如果值是一个数组,jquery将基于传统设置的值(如下所述)用相同的键序列化多个值。

从中我们可以看到,jquery将不是字符型的参数转换为get请求形式的参数。而使用postman不报错是因为postman有默认识别参数机制:将json转为字符串以及添加contentType信息:

 

3.问题解决

方法一:使用JSON.stringify处理json数据:

$("#a").click(function () {
                $.ajax({
                    url:"/foxbot/setRun/",
                    type:'post',
                    data:JSON.stringify({"param":true,"a":123}),//改动
                    contentType: 'application/json; charset=UTF-8',//改动
                    success:function (res) {

                    }
                })
            });

方法二:如果我们前台不想做改动,可以改动后台接收代码,后台使用request.POST.get("param")来接收参数,不过这种方法后台接受到数据类型的全部是字符串,即使前台json数据含有数值类型。

4.补充

为什么ajax又可以直接传对象,因为不加contentType:"application/json"的时候,发送类型变为默认的application/x-www-form-urlencoded,而这种方式会以键值对的形式将对象序列化。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用AjaxDjango传递参数的全部代码: 首先,在前端页面中引入jQuery库: ```html <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> ``` 然后,编写发送Ajax请求的JavaScript代码: ```javascript $.ajax({ url: "/your_django_view/", // Django视图函数的URL type: "POST", // 请求类型为POST data: {"param1": value1, "param2": value2}, // 请求参数,以字典形式传递 success: function(response) { // 请求成功时的回调函数,response为Django视图函数返回的数据 console.log(response); }, error: function(xhr, errmsg, err) { // 请求失败时的回调函数 console.log(xhr.status + ": " + errmsg); } }); ``` 在Django视图函数中,可以通过request.POST获取前端传递参数,例如: ```python from django.http import JsonResponse def your_django_view(request): param1 = request.POST.get("param1") param2 = request.POST.get("param2") # 处理请求参数 # ... # 返回JSON格式的响应 return JsonResponse({"result": "success"}) ``` 使用JS向Django传递参数的全部代码: 首先,在前端页面中定义一个form表单,包含需要传递参数: ```html <form action="/your_django_view/" method="POST" id="my-form"> <input type="hidden" name="param1" value="value1"> <input type="hidden" name="param2" value="value2"> <!-- 其他表单字段 --> <button type="submit">提交</button> </form> ``` 然后,编写JavaScript代码,在表单提交时自动发送请求: ```javascript document.getElementById("my-form").addEventListener("submit", function(event) { event.preventDefault(); // 阻止表单默认提交行为 var xhr = new XMLHttpRequest(); xhr.open("POST", "/your_django_view/"); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { // 请求完成时的回调函数 if (xhr.status === 200) { // 请求成功时的处理逻辑 console.log(xhr.responseText); } else { // 请求失败时的处理逻辑 console.log(xhr.status + ": " + xhr.statusText); } } }; xhr.send(new FormData(event.target)); }); ``` 在Django视图函数中,可以通过request.POST获取前端传递参数,例如: ```python from django.http import JsonResponse def your_django_view(request): param1 = request.POST.get("param1") param2 = request.POST.get("param2") # 处理请求参数 # ... # 返回JSON格式的响应 return JsonResponse({"result": "success"}) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值