Ajax

AJAX - 阿贾克斯
    1、什么是AJAX
        AJAX:Asynchronous Javascript And Xml(异步JS和Xml)
            同步访问:
                当客户端向服务器发送请求时,服务器在处理过程中,浏览器只能等待
                缺点:整个网页会刷新
            异步访问:
                当客户端向服务器发送请求时,服务器在处理过程中,浏览器可以做其他的事情,不需要一直等待,效率较高
                优点:局部刷新
        使用场合:
            1、搜索建议
            2、表单验证
            3、前后端完全分离
    2、AJAX核心对象 异步对象 - XMLHttpRequest
        1、什么是XMLHttpRequest
            主要称为‘异步对象’,代替浏览器向服务器发送请求并接收响应
            该对象主要由JS来提供
        2、创建异步对象
            主流的异步对象是XMLHttpRequest类型的,并且主流的浏览器(IE7+,Chrom,FireFox,Safari,Oper)已经全部支持该对象。低版本浏览器(IE7,IE6)是无法使用XMLHttpRequest,需要使用ActiveXObject来创建异步对象

            判断浏览器是否支持XMLHttpRequest
            if(window.XMLHttpRequest){
                //如果浏览器支持XMLHttpRequest的话,window.XMLHttpRequest则是一个非undefined的值,
                //如果浏览器不支持的话,此处就是一个undefined
                var xhr = new XMLHttpRquest();
            }else{
                //浏览器不支持XMLHttpRequest
                var xhr = new ActiveXobject("Microsoft.XMLHTTP");
            }

function createXhr(){
    if(window.XMLHttpRequest){
        return new XMLHttpRequest();
    }else {
        return new ActiveXObject('Microsoft.XMLHTTP');
    }
}
<button onclick="getXhr()">创建XHR</button>
    <script src="/static/js/common.js"></script>
    <script>
        function getXhr(){
            console.log(createXhr())
        }
    </script>
   <button onclick="getXhr()">创建XHR</button>
    <script>
        function getXhr(){
            //判断浏览器是否支持xhr
            console.log(window.XMLHttpRequest)
            if(window.XMLHttpRequest){
                var xhr = new XMLHttpRequest();
                console.log(xhr);
            }else{
                var xhr = new ActiveXObject('Microsoft.XMLHTTP');
            }
        }
    </script>

     3、xhr的成员
        1、方法 -  open()
            作用:创建/打开请求
            语法:xhr.open(method,url,asyn)
                method:指定请求的方式,取值为‘get’或‘post’
                url:请求地址,字符串
                asyn:指定是否使用异步的方式发送请求
                    true:使用异步
                    false:使用同步
                示例:
                    //1、获取xhr对象
                    var xhr =  createXhr();
                    //2、创建请求
                    xhr.open('get','/01_server',true);
        2、属性 - readyState
            作用:请求的状态,通过不同的请求状态来表示xhr与服务器的交互情况
                由0-4共5个值表示5个不同的状态
                0:请求尚未初始化
                1:已经与服务器建立连接
                2:服务器端已经接收请求
                3:请求正在处理中
                4:响应已经完成
        3、属性 - status
            作用:表示的是服务器端的响应状态码
                200:表示服务器正确处理所有的请求并给出响应
                403:请求被拒绝
                404:请求资源未找到
                500:服务器内部错误
        4、属性 - responseText
            作用:服务器端响应回来的文本
        5、事件 - onreadystatechange
            作用:每当readyState的值发生改变时要触发的操作 - 回调函数
            在此函数中,要判断当readyState的值为4并且status的值为200的时候,才可以正常的接收响应数据(responseText)
        6、方法 - send()
            作用:发送请求
            语法:xhr.send(body)
                body:表示请求主体,get请求的话,此处为null,post请求的话,此处为要提交的数据
    4、使用AJAX发送get请求
        1、步骤
            1、创建xhr对象
            2、创建请求 - open()
            3、设置回调函数 - onreadystatechange
            4、发送请求 - send()

<body>
    <button onclick='btnClick()'>点我试试!!!!</button>
    <div id="show"></div>
    <script src="/static/js/common.js"></script>
    <script>
        function btnClick(){
            //1、创建/获取xhr
            var xhr = createXhr();
            //2、创建请求 - open()
            xhr.open('get','/02_server/',true);
            //3、设置回调函数 - onreadystatechange
            xhr.onreadystatechange = function(){
                //当xhr.readyState的值为4,xhr.Status的值为200时,才可以接收xhr
                if(xhr.readyState ==4 && xhr.status==200){
                    var resText = xhr.responseText;
                    document.getElementById("show").innerHTML=resText;
                }
            }
            //4、发送请求 -send()
            xhr.send(null)
        }
    </script>

        2、发送带参数的get请求
            在请求地址中追加参数即可
            xhr.open('get','/02_server/?uname=sf.zh',true);

<body>
    <input id="input" type="text">
    <button id="send" >发送</button>
    <div id="show"></div>
    <script src="/static/js/common.js"></script>
    <script src="/static/js/jquery-1.11.3.js"></script>
    <script>
        $(function(){
            $('#send').click(function(){
                var name = $('input').val();
                xhr = createXhr();
                xhr.open('get','/03_server/?uname='+name,true);
                xhr.onreadystatechange=function(){
                    if(xhr.readyState==4 && xhr.status==200){
                        var resText = xhr.responseText;
                        $('#show').html(resText)
                    }
                }
                xhr.send()
            });
        });
    </script>
</body>

         5、使用AJAX发送post请求
            1、步骤
                1、创建/获取xhr
                2、创建请求 - open()
                 3、设置回调函数 - onreadystatechange
                4、发送请求 - send()
                    xhr.send('uname=sf.zh&upwd=123456');
            2、csrf验证
                必须手动提交csrfmiddlewaretoken的值到服务器,否则无法通过csrf的验证,服务器会返回403
                解决方案1:
                    1、在模板中,通过JS获取cookies中csrftoken的值

        var csrf = $.cookie('csrftoken')
                    2、将获取出来的值,拼成参数,再发送给服务器
                解决方案2:

      1、在模板中,通过一个隐藏域获取cookies中csrftoken的值

        <input type='hidden' name='csrfmiddlewaretoken' value='fvNkJBG2sJRXBpZKMNHYpUFygzMLUvnQ1iH>

        var csrf = $('[name=csrfmiddlewaretoken]').val();

      2、将获取出来的值,拼成参数,在发送给服务器

</head>
<body>
    <script src="/static/js/common.js"></script>
    <script src="/static/js/jquery-1.11.3.js"></script>
    <script>
        $(function(){
            $("#btnPost").click(function(){
                //1、创建xhr
                var xhr = createXhr()
                //2、创建请求
                xhr.open('post','/06_server/',true)
                //3、设置回调函数
                xhr.onreadystatechange = function(){
                    if(xhr.readyState == 4 && xhr.status==200){
                        alert(xhr.responseText)
                    }
                }
                //4、设置请求消息头
                xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
                //5、发送请求
                var uname = $('#uname').val();
                var csrf = $('[name=csrfmiddlewaretoken]').val();//属性选择器
                var params = 'uname='+uname+"&csrfmiddlewaretoken="+csrf
                xhr.send(params)
            })
        })
    </script>
    <div>
        {% csrf_token %}
        <p>
            用户名: <input type="text" id="uname">
        </p>
        <button id="btnPost">POST请求</button>
    </div>
</body>
</html>

            3、必须设置一个请求消息头 - Content-Type
                xhr.setRequsetHeader('Content-Type','application/x-www-form-urlencoded');
                注意:该操作要在xhr.send()之前增加
                Content-Type:application/x-www-form-urlencoded:表示任何数据都可提交
                Content-Type:text/plain;charset=UTF-8:表示只有英文和数字可以提交

<body>
    <div>
        <p>
            姓名:<input type="text" id="uname">
        </p>
        <p>
            密码:<input type="password" id="upwd">
        </p>
        <p>
            <input type="button" id="btnPost" value="POST">
        </p>
    </div>
    <p id="show"></p>
    <form>
        <!-- 为了向cookie中增加csrftoken值,可以写在任何位置,可以不写在form表单中,-->
        {% csrf_token %}
    </form>
    <script src="/static/js/common.js"></script>
    <script src="/static/js/jquery-1.11.3.js"></script>
    <script src="/static/js/jquery.cookie.js"></script>
    <script>
        $(function(){
            $('#btnPost').click(function(){
                //1、获取xhr
                var xhr = createXhr();
                //2、创建请求
                xhr.open('post','/04_server/',true);
                //3、设置回调函数
                xhr.onreadystatechange = function () {
                    if(xhr.readyState==4 && xhr.status==200){
                        $('#show').html(xhr.responseText);
                    }
                }
                //设置请求头
                xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
                //4、发送请求
                //从cookie中获取scrftoken的值
                var csrf = $.cookie('csrftoken')
                var uname = $("#uname").val();
                var upwd = $('#upwd').val();
                var params = "uname="+uname+"&upwd="+upwd+"&csrfmiddlewaretoken="+csrf;
                xhr.send(params)
            })
        })
    </script>
</body>

 JSON
    1、JSON的介绍
        JSON:JavaScript Object Notation(表现形式)
        将复杂的数据按照JS对象的格式进行响应
    2、JSON表现
        1、JSON可以表示单个对象
            1、使用{}表示单个对象
            2、在{}中,使用key:value的形式来表示数据(属性和值)
            3、key必须使用双引号引起来(单引号有时不好用)
            4、value如果是字符串的话,也必须使用双引号引起来,是数字的话可以引也可以不引
            var obj = {
                "name":"xdl",
                "age": 20,
                "gender":"男",
            }
            取值:
            obj.name
            obj.age
            obj.gender
        2、json可以表示一个数组
            1、使用[]表示一个数组
            2、在数组中允许包含若干普通数据 或 json对象
                1、使用json数组表示普通数据
                    var arr = ["xdl","gj"]
                2、使用json数组表示若干对象
                    var arr = [
                        {
                            "name":"xdl",
                            "age": 20,
                            "gender":"男",
                        },
                        {
                            "name":"gj",
                            "age": 18,
                            "gender":"女",
                        },
                    ]
                3、取值
                    方法1:
                        $(arr).each(function(i,obj){
                            console.log(i+":"+obj.name);
                        })
                    方法2:            
                        $.each(arr,function (i,obj){
                            console.log(i+":"+obj.name);
                        })
            3、后台处理json
                1、前后台json数据交互流程(后→前)
                    1、后台先获取数据
                        类型:
                            1、元祖
                            2、列表
                            3、字典
                            4、QuerySet
                    2、在后台将数据转换为符合json格式的字符串
                    3、在后台将json格式的字符串响应给前端
                        return HttpResponse(json格式字串)
                    4、在前端,将响应回来的json串解析成json对象
                2、Python(Django)中的json处理
                    1、元祖,列表,字典
                        使用Python提供的json模块就可以完成转换
                        import json
                        json.dumps(元祖|列表|字典)
                    2、Django中的查询结果集 - QuerySet
                        使用Django提供的序列化类 完成QuerySet到json字符串的转换
                        from django.core import serializers
                        jsonStr = serializers.serialize("json",QuerySet)

def server09_views(request):
    user = User.objects.all()
    jsonStr = serializers.serialize('json',user)
    return HttpResponse(jsonStr)

                        在Js中通过JSON.parse()得到的结果
                        [
                            {
                            "model": "index.user",
                            "pk": 1, #主键
                            "fields": #除了主键之外的所有字段
                                    {
                                        "uname": "xdl",
                                        "upwd": "123456",
                                        "uphone": "123456789",
                                        "uemail": "aaa@163.com"
                                    }
                            }
                        ]
                    3、django中查询单个对象
                        使用Entry.objects.get(条件)查询单条数据,是不允许被序列化为json格式的
                        1、方案1
                            使用Entry.objects.filter()来替换Entry.objects.get(),替换后则可以正常使用serializers
                        2、方案2
                            将Entry.objects.get()得到的单个对象转换成字典后再使用json.dumps()
                                class User(models.Mode):
                                    name = models.CharField(maxlength=30)
                                    pwd = models.CharField(maxlengtj=30)
                                    def to_dict(self):
                                        dic = {
                                            'name':self.name,
                                            'pwd':self.pwd
                                        }
                                        return dic
                                user = User.objects.get(id=1)
                                jsonStr = json.dumps(user.to_dict())
                3、前端处理json
                    将后端响应回来的json字符串转换成json对象
                    在JS中:
                        var json对象 = JSON.parse(json字符串)
jQuery AJAX
    在jquery中提供了对原生ajax的封装操作
    1、$obj.load(),该方法发送的是GET方法
        作用:异步加载数据到$obj元素中
        语法:$obj.load(url,data,callback)
            1、url:异步请求的地址
            2、data:传递给服务器端的数据(可选)
                1、可以传递普通的字符串
                    “name=xdl&age=20”
                2、可以传递json
                    {
                        "name":"xdl",
                        "age":20
                    }
            3、callback:异步请求完成后的回调函数(可选)
                function(resText,statusText){
                    resText:响应数据

         statusText:响应的状态文本,比如200代表的状态文本就是success
                }

<body>
    <button id="btnload">发送load</button>
    <div id="show">
    </div>
    <script src="/static/js/jquery-1.11.3.js"></script>
    <script>
        $(function(){
            $('#btnload').click(function () {
                var params = "uname=xdl&uage=20";
                $('#show').load('/09_server/',params,function (resText,statusText) {
                    //resText:响应数据(可选):姓名:xdl,年龄:20
                    console.log(resText);
                    //statusText:响应的状态文本(可选):success
                    console.log(statusText);
                    var arr = JSON.parse(resText);
                    $.each(arr,function(i,obj){
                        console.log(obj.pk)//主键为1
                        console.log(obj.fields.uname)//名字为xdl
                    })
                })
            })
        })
    </script>
</body>

     2、$.get(),发送的是GET请求
        语法:$.get(url,data,callback,type)
            1、url:异步请求的地址
            2、data:请求提交的参数(可选)
            3、callback:请求成功时的回调函数(可选)
                function(data){
                    data:表示的是响应回来的的数据
                }
            4、type:指定返回内容的格式类型(可选)
                1、html:响应回来的内容是html文本
                2、text:响应回来的内容是text文本
                3、json:响应回来的内容是json对象

<body>
    <button id="btnGet"> jquery ajax get</button>
    <div id="show"></div>
    <script src="/static/js/jquery-1.11.3.js"></script>
    <script>
        $(function(){
            var params = {
                'name':'xdl',
                'age':20,
            }
            $("#btnGet").click(function(){
                $.get('/10_server/',params,function(data){
                    //$("#show").html(data);
                    var html="";
                    $.each(data,function(i,obj){
                        html+="<p>";
                            html+="<b>"+obj.name+"</b>";
                            html+="<b>"+obj.age+"</>";
                        html+="</p>"
                    });
                    $("#show").html(html)
                },'json');
            });
        });
    </script>
</body>

    3、$.post(),发送的是POST请求
        语法:$.get(url,data,callback,type)
            参数同$.get()
        注意:该方法需要csrf验证
            var data = {
                "csrfmiddlewaretoken":$.cookie('csrftoken')
            }

<body>
    <button id="btnPost">jq ajax Post </button>
    <script src="../js/jquery-1.11.3.js"></script>//静态文件加载方式
    <script src="../js/jquery.cookie.js"></script>
    <script>
        $(function () {
            $('#btnPost').click(function () {
                var params = {
                    "csrfmiddlewaretoken":$.cookie('csrftoken')
                }
                $.post('/11_server/',params,function (data) {
                    alert(data)
                })
            })
        })
    </script>
</body>

    4、$.ajax()
        特点:所有的操作都可以自己定制
        语法:$.ajax({json对象})
            json对象:
                1、url:字符串,要异步请求的地址
                2、type:字符串,提交方式,get 或 post
                3、data:json对象或字符串,要传递到后台服务器的参数,参数名不需要加引号,值需要加引号

      data :{
                uphone:‘123456’,
                csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val()
            },
                4、dataType:字符串,指定响应回来的数据的类型
                    1、'html':响应回来的数据是html文本
                    2、'text':响应回来的数据是text文本
                    3、'script':响应回来的数据是JavaScript代码
                    4、'json':响应回来的数据是json对象
                    5、'xml':响应回来的数据是xml文档
                    6、'jsonp':jsonp格式,跨域时使用,(在本网站访问其他网站就是跨域)
                5、success:请求和响应成功时的回调函数
                    success:function(data,textStatus){
                        data:响应数据
                        textStatus:响应状态文本
                    }
                6、error:请求和响应出错时的回调函数
                    error:function(xhr,textStatus){
                        xhr:异步请求对象
                        textStatus:响应状态文本
                    }
                7、async:指定是否异步方式
                    true:使用异步方式
                    false:使用同步方式
                    默认为true

<body>
    选择省份: <select name="" id="selPro"></select>
    <select name="" id="selCity"></select>
    <script src="/static/js/jquery-1.11.3.js"></script>
    <script>
        function loadPro(){
            $.ajax({
                url:'/12_server/',
                type:'get',
                dataType:'json',
                async:false,
                success:function(data){
                     var html="";
                     $.each(data,function (i,obj) {
                         html+="<option value="+ obj.pk +">";
                            html+=obj.fields.name;
                         html+="</option>";
                     });
                     $('#selPro').html(html) ;
                }
            });
        }
        function loadCity(id){
            $.ajax({
                url:'/13_server/',
                type:'get',
                data:"id="+id,
                dataType:'json',
                success:function(data,testStatus){
                    console.log(testStatus);//success
                    var html="";
                     $.each(data,function (i,obj) {
                         html+="<option value="+ obj.pk +">";
                            html+=obj.fields.name;
                         html+="</option>";
                     });
                     $('#selCity').html(html) ;
                },
            });
        }
        $(function () {
            loadPro();
            //初始话就要显示城市信息,但需需要loadPro()返回为同步请求
            loadCity($("#selPro").val())
            $("#selPro").change(function(){
                loadCity($(this).val());
            })
        })
    </script>
</body>
def server12_views(request):
    proList = Province.objects.all()
    jsonStr = serializers.serialize('json',proList)
    return HttpResponse(jsonStr)
def server13_views(request):
    id = request.GET['id']
    province = Province.objects.get(id=id)
    #反向查询
    cityList = province.city_set.all()
    jsonStr = serializers.serialize('json',cityList)
    return HttpResponse(jsonStr)

 


              

posted @ 2018-09-03 12:12  xdl_smile  阅读(187)  评论(0编辑  收藏  举报