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 thetraditional
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,而这种方式会以键值对的形式将对象序列化。