关于ajax post 数据时django中request.body与request.POST问题

96
寻找无双丶
2017.10.18 11:16* 字数 916

在django1.11的官网中是这么解释的:

HttpRequest.body:
The raw HTTP request body as a byte string. This is useful for processing data in different ways than conventional HTML forms: binary images, XML payload etc. For processing conventional form data, use HttpRequest.POST.

原始的http字节请求。在处理二进制图片,XML负载时。当处理的常规的表单数据时,使用HttpRequest.POST

HttpRequest.POST:
A dictionary-like object containing all given HTTP POST parameters, providing that the request contains form data. See the QueryDict documentation below. If you need to access raw or non-form data posted in the request, access this through the HttpRequest.body attribute instead.
It’s possible that a request can come in via POST with an empty POST dictionary – if, say, a form is requested via the POST HTTP method but does not include form data. Therefore, you shouldn’t use if request.POST to check for use of the POST method; instead, use if request.method == "POST" (see HttpRequest.method).
POST does not include file-upload information. See FILES.

request.POST是一个字典一样的数据,见QueryDict。适用于表单,当你需要获取原始数据或者非表单数据时,请用request.body。该方法文件上传不包括文件上传,见HttpRequest.FILES


例子1

ajax中:
        $.ajax({
        type: "post",
        url: 'http://192.168.124.149:8000/tempaction/',
        traditional: true ,                  // 1
        //contentType: "application/json"  , 注意这一行注释了
        dataType: "json",
        data: {
            type: [1,2,3],

        },
        success: function (data) {
            console.log(data)
        }
    });
django中print以下reqeust的属性:
request.content_type -----> application/x-www-form-urlencoded
request.body -----> b'type=1&type=2&type=3'
request.POST -----> <QueryDict: {'type': ['1', '2', '3']}>
request.POST.get['type'] -----> 3
request.POST.getlist----->['1', '2', '3']
  1. 很多时候,我们用 Ajax 提交数据时,也是使用这种方式。例如 JQuery 和 QWrap 的 Ajax,Content-Type 默认值都是「application/x-www-form-urlencoded;charset=utf-8」.其次,提交的数据按照 key1=val1&key2=val2 的方式进行编码,key 和 val 都进行了 URL 转码。大部分服务端语言都对这种方式有很好的支持
  2. 但是这里标记为1的那一行,如果没有traditional: true这个参数(很乱,有兴趣的可以自己试一下),在java,python后台是无法取到参数的,因为jQuery需要调用jQuery.param序列化参数jQuery.param( obj, traditional )默认的话,traditional为false,即jquery会深度序列化参数对象,以适应如PHP和Ruby on Rails框架, 但servelt api,python之类的无法处理,我们可以通过设置traditional 为true阻止深度序列化,然后序列化结果就如上面的一样了
  3. 关于request.POST.get['type']值为3,为什么只取最后一个值,可取django官网查询,这也就有了下面那个getlist()方法.但是有瑕疵,因为得到的list中的元素都是字符串,要自行转换,稍显麻烦

例子2

ajax中:
        $.ajax({
            type: "post",
            url: 'http://192.168.124.149:8000/tempaction/',
            contentType: "application/json"  ,
            dataType: "json",
            data: JSON.stringify(({     //2
                type: 'add',
                person: [
                    {
                        id: '1',
                        info: ['andy', '22']
                    }, {
                        id: '2',
                        info: ['lily', '21']
                    }
                ]
            })),
django中print以下reqeust的属性:
request.content_type -----> application/json
request.body -----> b'{"type":"add","person":[{"id":"1","info":["andy","22"]},{"id":"2","info":["lily","21"]}]}'
json.loads(request.body.decode('utf-8')) ------> 一个完整数据,即python字典
request.POST -----> <QueryDict: {}>
  1. 说一下标记的2,JSON.stringify:The JSON.stringify() method converts a JavaScript value to a JSON string,.http传输中用的是字符串,准确的来说是json字符串,这个方法将一个js对象装换为json字符串,传输到后端,后端接收,然后解码后再反序列化一下,就获得数据了.这样的话后端传到前端应该也是这么个道理 =.=,不知道这种说法有没有问题
  2. 此时request.POST中为空

总结

  • request.POST适用于接收表单数据,表单数据一般是比较简单,没有嵌套.面对复杂的数据时,即使像例子1中一个简单的list接受后都会变形(元素变为字符串),处理起来没那么顺手.
  • request.body可以方便的提交复杂的结构化数据,特别适合 RESTful 的接口
  • 因为本人前端知识比较烂,讲的都是一些非常基础的东西,但对于我来说,查阅了一些资料后,受益颇多.有说错的地方欢迎指点,相互交流.

相关链接

https://ask.helplib.com/436351
http://www.cnblogs.com/aaronjs/p/4165049.html
https://my.oschina.net/i33/blog/119506
http://blog.csdn.net/panyu_smd/article/details/70174126

Python,简单优于复杂
Web note ad 1