• [Python自学] day-23 (1) (原生Ajax、jQuery Ajax、iframe)


    一、原生Ajax

    在之前学习jQuery的时候,我们选择使用1.x版本,而没有选择使用2.x、3.x版本。

    主要是因为1.x版本兼容以前比较老的浏览器,例如IE6 IE7等。

    例如要使用Ajax,低版本的浏览器可能不支持xmlHttpRequest对象,而只支持另外一种IE使用的对象叫ActiveXObject。

    在jQuery 1.x中,jquery.ajax会对这两种对象进行上层封装,也就是说两种都支持。

    但在2.x和3.x中,jquery就放弃了低版本的浏览器,而只支持XHR对象

    1.使用原生Ajax(GET请求)

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Ajax</title>
    </head>
    <body>
    <input type="text"/>
    <input type="button" value="Ajax" onclick="send_ajax();"/>
    <script>
        // onclick事件,发送原生ajax请求
        function send_ajax() {
            // 创建一个xhr对象
            var xhr = new XMLHttpRequest();
            // 建立异步连接,第三个参数true表示异步
            xhr.open('GET', '/ajaxproc/', true);
            // 指定回调函数,每当readystate的值改变时,function就会被执行,当readystate为4时表示收到返回的数据
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    // 打印收到的数据
                    console.log(xhr.responseText);
                    // 打印收到的状态码,这个码是由视图函数HttpResponse(status=200)返回
                    console.log(xhr.status);
                    // 打印状态码对应的文本,HttpResponse(reason='文本')返回
                    console.log(xhr.statusText);
                }
            };
            // 发送数据
            xhr.send("username=root;password=123456");
        }
    </script>
    </body>
    </html>

    2.使用原生Ajax(POST请求)

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Ajax</title>
    </head>
    <body>
    <input type="text"/>
    <input type="button" value="Ajax" onclick="Ajax1();"/>
    <script>
        // onclick事件,发送原生ajax请求
        function Ajax1() {
            // 创建一个xhr对象
            var xhr = new XMLHttpRequest();
            // 建立异步连接,第三个参数true表示异步
            xhr.open('POST', '/ajaxproc/', true);
            // 指定回调函数,每当readystate的值改变时,function就会被执行,当readystate为4时表示收到返回的数据
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    // 打印收到的数据
                    console.log(xhr.responseText);
                    // 打印收到的状态码,这个码是由视图函数HttpResponse(status=200)返回
                    console.log(xhr.status);
                    // 打印状态码对应的文本,HttpResponse(reason='文本')返回
                    console.log(xhr.statusText);
                }
            };
            // 要发post请求,必须设置请求头
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
            // 主要要设置csrf,这里省略,参考CSRF章节
            // 发送数据
            xhr.send("username=root;password=1234;");
        }
    </script>
    </body>
    </html>

    3.对应视图函数

    def ajax(request):
        return render(request, 'ajax.html')
    
    
    def ajaxproc(request):
        import json
        def check_data(u, p):
            if u == 'leo' and p == '123456':
                return True
            else:
                return False
        if request.method == 'GET':
            if check_data(request.GET.get('username'), request.GET.get('password')):
                ret = {'code': 2000, 'data': "正确"}
            else:
                ret = {'code': 4000, 'data': "错误"}
            return HttpResponse(json.dumps(ret), status=200, reason="OK")
        if request.method == 'POST':
            if check_data(request.POST.get('username'), request.POST.get('password')):
                ret = {'code': 2000, 'data': "正确"}
            else:
                ret = {'code': 4000, 'data': "错误"}
            return HttpResponse(json.dumps(ret), status=200, reason="OK")

    4.AJAX返回结果

    二、XMLHttpResponse对象介绍

    1.XMLHttpResponse对象的主要方法

    a. void open(String method,String url,Boolen async)
       用于创建请求
    
       参数:
           method: 请求方式(字符串类型),如:POST、GET、DELETE...
           url:    要请求的地址(字符串类型)
           async:  是否异步(布尔类型)
    
    b. void send(String body)
        用于发送请求
    
        参数:
            body: 要发送的数据(字符串类型)
    
    c. void setRequestHeader(String header,String value)
        用于设置请求头
    
        参数:
            header: 请求头的key(字符串类型)
            vlaue:  请求头的value(字符串类型)
    
    d. String getAllResponseHeaders()
        获取所有响应头
    
        返回值:
            响应头数据(字符串类型)
    
    e. String getResponseHeader(String header)
        获取响应头中指定header的值
    
        参数:
            header: 响应头的key(字符串类型)
    
        返回值:
            响应头中指定的header对应的值
    
    f. void abort()
    
        终止请求

    2.XMLHttpResponse对象的主要属性

    a. Number readyState
       状态值(整数)
     
       详细:
          0-未初始化,尚未调用open()方法;
          1-启动,调用了open()方法,未调用send()方法;
          2-发送,已经调用了send()方法,未接收到响应;
          3-接收,已经接收到部分响应数据;
          4-完成,已经接收到全部响应数据;
     
    b. Function onreadystatechange
       当readyState的值改变时自动触发执行其对应的函数(回调函数)
     
    c. String responseText
       服务器返回的数据(字符串类型)
     
    d. XmlDocument responseXML
       服务器返回的数据(Xml对象)
     
    e. Number states
       状态码(整数),如:200、404...
     
    f. String statesText
       状态文本(字符串),如:OK、NotFound...

    三、兼容性(跨浏览器支持

    主要针对旧版本IE浏览器和chrome浏览器之间的兼容。

    XmlHttpRequest
      IE7+, Firefox, Chrome, Opera, etc.

    ActiveXObject("Microsoft.XMLHTTP")

      IE6, IE5

    如果我们想兼容低版本的IE浏览器,也就说当没有XMLHttpResponse的时候,使用ActiveXObject。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Ajax</title>
    </head>
    <body>
    <input type="text"/>
    <input type="button" value="Ajax" onclick="Ajax1();"/>
    <script>
        // 获取XHR
        function getXHR(){
            var xhr=null;
            if (XMLHttpRequest){
                xhr = new XMLHttpRequest();
            }else{
                xhr = new ActiveXObject("Microsoft.XMLHTTP");
            }
        }
        // onclick事件,发送原生ajax请求
        function Ajax1() {
            // 创建一个xhr对象
            var xhr = getXHR();
            // 建立异步连接,第三个参数true表示异步
            xhr.open('POST', '/ajaxproc/', true);
            // 指定回调函数,每当readystate的值改变时,function就会被执行,当readystate为4时表示收到返回的数据
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    // 打印收到的数据
                    console.log(xhr.responseText);
                    // 打印收到的状态码,这个码是由视图函数HttpResponse(status=200)返回
                    console.log(xhr.status);
                    // 打印状态码对应的文本,HttpResponse(reason='文本')返回
                    console.log(xhr.statusText);
                }
            };
            // 要发post请求,必须设置请求头
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
            // 主要要设置csrf,这里省略,参考CSRF章节
            // 发送数据
            xhr.send("username=root;password=1234;");
        }
    </script>
    </body>
    </html>

    四、jQuery的Ajax

    在前面我们已经使用过jQuery封装的Ajax。参照:[Python自学] day-20 (Django-ORM、Ajax) 第三节。

    function Ajax1(){
        $.ajax({
            url: '/ajaxproc/',
            type: 'POST',
            data: {'username':'leo','password':'123456'},
            success:function(data,str,xhr_obj) {
                console.log(data);
                console.log(typeof(str)); //打印success(string)
                console.log(xhr_obj);
            }
        })
    }

    假设我们使用jQuery.ajax,我们所定义的回调函数其实可以接收三个参数。第一个参数data就是服务器的返回值response。第二个参数返回的是一个字符串,成功返回'success'。

    第三个参数很关键,他其实就是返回的$.ajax底层调用的XMLHttpResponse对象,也就是原生Ajax中我们new出来的xhr对象。

    那就意味着,我们的全部数据都可以从xhr_obj这个参数中去获取:

    function Ajax1(){
        $.ajax({
            url: '/ajaxproc/',
            type: 'POST',
            data: {'username':'leo','password':'123456'},
            success:function(data,str,xhr_obj) {
                console.log(xhr_obj.responseText);
                console.log(xhr_obj.status);
                console.log(xhr_obj.statusText);
            }
        })
    }

    查看打印结果:

    可以看到,这和原生Ajax一模一样。

    五、伪Ajax

    1.认识iframe标签

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Iframe</title>
    </head>
    <body>
    <iframe id="ifm" src="http://www.baidu.com" style="height: 400px; 800px;"></iframe>
    <input id='ifm_url' type="text"/>
    <input type="button" value="发送" onclick="iframe_send();"/>
    <script src="/static/jquery-1.12.4.js"></script>
    <script>
        function iframe_send(){
            var url = $("#ifm_url").val();
            console.log(url);
            $("#ifm").attr('src',url);
        }
    </script>
    </body>
    </html>

    页面效果:

    可以看到,中间的百度页面就是iframe标签。因为<iframe src="http://www.baidu.com">中src的默认值是百度。

    当我们在后面的text框中输入http://www.douyu.com,并点击发送,<iframe>标签的src被修改为斗鱼的url。

    此时<iframe>标签就会将斗鱼的页面请求回来,并且页面是不刷新的。

    效果:

     所以,iframe可以执行类似Ajax的异步操作,称之为伪Ajax操作。。

    2.利用iframe标签提交表单

    我们可以在表单中利用iframe为其提交数据:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Iframe</title>
    </head>
    <body>
    <form action="/ajaxproc/" method="post" target="ifm1">
        <iframe name="ifm1"></iframe>
        <input type="text" name="username"/>
        <input type="text" name="password"/>
        <input type="text" name="email"/>
        <input type="submit" name="Form提交"/>
    </form>
    </body>
    </html>

    这样的话,这个表单提交的时候就会将数据交给iframe提交,返回值显示在iframe框中。

    效果如下:

    注意:

    利用iframe时,视图函数需要加一个装饰器

    from django.views.decorators.clickjacking import xframe_options_exempt
    
    
    @xframe_options_exempt
    def ajaxproc(request):
        #......

    如果不只用该装饰器,则会报错:

     

    3.获取iframe的值

    form利用iframe提交表单后,返回值是显示在iframe窗口中的,我们要如何来获取这些数据?

    首先,我们看以下iframe中显示的值是什么:

     可以看到,iframe中实际上嵌套了一个html页面。

    当返回的数据返回到页面,并且往iframe中写时,iframe要触发一个onload事件。我们可以利用这个事件,来获取返回的数据。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Iframe</title>
    </head>
    <body>
    <form action="/ajaxproc/" method="post" target="ifm1">
        <iframe id="ifm1" name="ifm1"></iframe>
        <input type="text" name="username"/>
        <input type="text" name="password"/>
        <input type="text" name="email"/>
        <input type="submit" name="Form提交" onclick="bind_onload_event();"/>
    </form>
    <script src="/static/jquery-1.12.4.js"></script>
    <script>
        function bind_onload_event(){
            //为iframe绑定onload事件函数,当数据回来时,则会触发
            $("#ifm1").load(function(){
                //在这里去获取数据
                var text = $("#ifm1").contents().find('body').text();
                console.log(text);
                var obj = JSON.parse(text);
                // 拿到obj后,就可以随意处理数据了
                //todo..
            })
        }
    </script>
    </body>
    </html>

    这样,我们就通过iframe发送异步请求,并成功获得了返回数据。在页面上,我们只需要隐藏iframe框就可以了。

  • 相关阅读:
    MVC 学习(二)之Linq to Sql 简单Demo
    MVC 学习(一)Linq to Entities 简单Demo
    MVC学习(三)Code-First Demo
    pickle 模块
    json 模块
    sys 模块
    os 模块
    random(随机)模块
    time 模块
    python之函数基础
  • 原文地址:https://www.cnblogs.com/leokale-zz/p/12102076.html
Copyright © 2020-2023  润新知