ajax参数补充

ajax参数补充

contentType

当我们使用form表单提交数据时,有一个enctype属性,默认情况下不写

此时我们提交数据时,会默认将数据以application/x-www-form-urlencoded的编码方式发送

该形式的数据为"k1=v1&k2=v2"格式,可以看成是一组组的键值对

但是当我们要发送图片等二进制文件时,上面的形式就无法实现了,此时我们会将enctype属性设置为form-data

这时我们就既可以发送键值对的数据,又可以发送较大的二进制文件了

同样,在使用ajax发送数据时,默认情况下,我们发送的get和post请求都是以application/x-www-form-urlencoded的编码方式发送的

但是我现在想要向后端发送一个json字符串形式的数据,该怎么办呢

这里我们就需要使用ajax里的contentType参数

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
    <script src="http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>

<button class="json_send">send</button>
{% csrf_token %}
<script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.js"></script>
<script>
    $(".json_send").click(function () {


            $.ajax({
            url:"/ajax_send/",
            data:JSON.stringify({"k1":"v1"}),
            type:"post",
            contentType:"application/json",
            success:function (data) {
                console.log(data)
            }

        });

</script>
复制代码

如果以上面的形式直接发送,我们会发现后端接收时,request.POST和request.GET内都取不到值

def ajax_send(request):
    import json
    print(request.GET)  # <QueryDict: {}>
    print(request.POST)  # <QueryDict: {}>
    print(request.body.decode())  #  {"k1":"v1"}return HttpResponse("OK")

这就要从帮助Django处理http请求的wsgiref模块说起了

该模块主要做了三件事:

1.封装了一个socket对象,通过该对象与客户端建立连接

2.按照http协议解析数据

3.按照http协议封装响应数据

当该模块解析数据时,会有一定的规则

wsgi:
if  content_type: url_encoded:
    request.body :post(get)数据-------> request.POST(GET)

当数据格式为application/x-www-form-urlencoded时,他会把数据写到request.POST或者request.GET中,如果为其它格式,则不会,此时我们如果想拿到数据必须从request.body中取

这样我们就完成了json字符串格式的数据发送,但是我们注意到这里我们发送的是post请求,但是却未带csrftoken的相关数据,如果通过中间件的话,这个请求会被拒绝,那我们该如何将csrftoken的值一起发送过去呢

这里我们先研究一下csrftoken的中间件是如何取相应的值的

复制代码
CsrfViewMiddleware:
                
if random_str=request.POST.get("csrfmiddlewaretoken")
     if  random_str=="347289asd328":
         pass 
 elif request.META.get("X-CSRFToken"):                    
        request.META.get("X-CSRFToken")=="asdasdh23470ahsd37sa"    
else:
     return Htttpresponse("forbidden error")
复制代码

我们发现中间件会先从request.POST中取,但是我们的数据不会被放到request.POST中,所以取不到

这时中间件又会从请求头部的X-CSRFToken中取值,如果还取不到,那么会forbidden

所以我们此时就要想办法将csrftoken的值放到请求头的X-CSRFToken中

其实每当我们发送一次请求时,我们会发现在我们的COOKIE中也会带有csrftoken的相关内容,此时就从中取值放入X-CSRFToken中

复制代码
<script src="{% static 'js/jquery.cookie.js' %}"></script>  // 必须要引用,不然无法使用$.cookie方法

$.ajax({
 
headers:{"X-CSRFToken":$.cookie('csrftoken')},
 
})
复制代码

我们的代码为

复制代码
$(".json_send").click(function () {
        
        $.ajax({
            url:"/ajax_send/",
            data:JSON.stringify({"k1":"v1"}),
            type:"post",
            headers:{"X-CSRFToken":$()},
            contentType:"application/json",
            success:function (data) {
                console.log(data)
            }

        });
复制代码

dataType

该属性表示我们期待服务器发送回来的数据是一个什么类型

如:dataType:json,表示我们期待服务器端发送的是一个json格式的数据

这个属性并不会改变服务器端的内容,但是当客户端拿到服务器端的数据后,ajax方法会将数据进行parser操作,得到我们想要的类型

error和complete

复制代码
$(".send_Ajax").click(function(){

           $.ajax({
               url:"/handle_Ajax/",
               type:"POST",
               data:{username:"Yuan",password:123},

               success:function(data){
                   alert(data)
               },

                 //=================== error============

                error: function (jqXHR, textStatus, err) {

                        // jqXHR: jQuery增强的xhr
                        // textStatus: 请求完成状态
                        // err: 底层通过throw抛出的异常对象,值与错误类型有关
                        console.log(arguments);
                    },

                 //=================== complete============

                complete: function (jqXHR, textStatus) {
                    // jqXHR: jQuery增强的xhr
                    // textStatus: 请求完成状态 success | error
                    console.log('statusCode: %d, statusText: %s', jqXHR.status, jqXHR.statusText);
                    console.log('textStatus: %s', textStatus);
                },
复制代码

我们使用success回调函数是在执行不出错时执行的,如果执行过程中出了错误,则会执行error的回调函数,而complete是不管出不出错都会执行的

posted @ 2018-03-02 18:50  邯城吴彦祖  阅读(127)  评论(0编辑  收藏  举报