zoukankan      html  css  js  c++  java
  • 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是不管出不出错都会执行的

  • 相关阅读:
    安卓的sqlite增删改
    C#访问MySQL数据库(winform+EF)
    Sqlite在.NET下的使用和Sqlite数据库清理
    WPF小笔记-Popup拖动
    WPF自定义窗口最大化显示任务栏
    什么是Hash?什么是Hash算法或哈希函数?什么是map?什么是HashMap?HashMap的实现原理或者工作原理?HashMap是线程安全的吗?为什么?如何解决?
    字符串转换整数
    系统顺序图与顺序图区别,以及根据顺序图写代码
    设计领域模型有哪些难点?有哪些指导原则?
    斐波那契数列java实现
  • 原文地址:https://www.cnblogs.com/QQ279366/p/8494694.html
Copyright © 2011-2022 走看看