• Python全栈之路-Django(十六)


    今日内容:Ajax
    http://www.cnblogs.com/wupeiqi/articles/5703697.html

    1 Ajax介绍

    AJAX,Asynchronous JavaScript and XML (异步的JavaScript和XML),一种创建交互式网页应用的网页开发技术方案。

    1.1异步的JavaScript:

    使用 【JavaScript语言】 以及 相关【浏览器提供类库】 的功能向服务端发送请求,当服务端处理完请求之后,【自动执行某个JavaScript的回调函数】。

    PS:以上请求和响应的整个过程是【偷偷】进行的,页面上无任何感知。

    1.2 XML

    XML是一种标记语言,是Ajax在和后台交互时传输数据的格式之一
    利用AJAX可以做:

    • 注册时,输入用户名自动检测用户是否已经存在。
    • 登陆时,提示用户名密码错误
    • 删除数据行时,将行ID发送到后台,后台在数据库中删除,数据库删除成功后,在页面DOM中将数据行也删除。

    1.3 Ajax定义总结

    偷偷向后台发请求  
    

    2 Ajax发送数据

    • 原生Ajax,利用XMLHttpRequest对象
    • JQuery Ajax,内部基于原生Ajax
    • 伪Ajax,非XMLHttpRequest

    2.1 原生Ajax

    1、XmlHttpRequest对象介绍
    XmlHttpRequest对象的主要方法:

    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()
     
        终止请求
    

    XmlHttpRequest对象的主要属性:

    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...
    

    实例:

    a. XMLHttpRequest

    GET请求:

    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4){
            alert(xhr.responseText);
        }
    };
    xhr.open('GET','/add2/?i1=12&i2=19');
    xhr.send();
    

    POST请求:

    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4){
            alert(xhr.responseText);
        }
    };
    xhr.open('POST','/add2/');
    xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
    xhr.send("i1=12&i2=19");
    

    2.2 伪Ajax

    伪Ajax,非XMLHttpRequest,利用iframe标签 不刷新打开页面发送HTTP请求

    app01.views.py

    def fake_ajax(request):
        if request.method == 'GET':
            return render(request, 'fake_ajax.html')
        else:
            print(request.POST)
            return HttpResponse('...')
    

    templates.fake_ajax.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <form id="f1" action="/fake_ajax/" method="post" target="ifr" >
        <iframe id="ifr" frameborder="1" name="ifr" style="display: none;"></iframe>
        <input type="text" name="user">
        <input type="button" value="提交" onclick="submitForm();">
    </form>
    <script>
        function submitForm() {
            document.getElementById('f1').submit();
            document.getElementById('ifr').onload = LoadIframe;
    
        }
        function LoadIframe() {
            var content = document.getElementById('ifr').contentWindow.document.body.innerText
            alert(content)
        }
    </script>
    </body>
    </html>
    

    2.3 实例

    templates.index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>首页</h1>
        <input type="text" id="i1">
        +
        <input type="text" id="i2">
        =
        <input type="text" id="i3">
    
        <input type="button" id="btn1" value="JQuery Ajax" onclick="add1();">
        <input type="button" id="btn2" value="原生 Ajax" onclick="add2();">
        <script src="/static/jquery-3.2.1.min.js"></script>
        <script>
            function add1() {
                $.ajax({
                    url: '/add1/',
                    type: 'POST',
                    data: {'i1': $('#i1').val(),'i2':$('#i2').val()},
                    success: function (arg) {
                        $('#i3').val(arg)
                    }
                })
            }
            function add2() {
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function () {
                   if (xhr.readyState ==4){
                       alert(xhr.responseText);
                   }
                };
                // xhr.open('GET','/add2/?i1=12&i2=19');
                xhr.open('POST','/add2/');
                xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                xhr.send('i1=12&i2=19');
            }
        </script>
    </body>
    </html>
    

    app01.views.py

    def add1(request):
        i1 = int(request.POST.get('i1'))
        i2 = int(request.POST.get('i2'))
        return HttpResponse(i1+i2)
    
    
    def add2(request):
        if request.method == 'GET':
            i1 = int(request.GET.get('i1'))
            i2 = int(request.GET.get('i2'))
            print(i1+i2)
            return HttpResponse(i1+i2)
        else:
            # i1 = int(request.POST.get('i1'))
            # i2 = int(request.POST.get('i2'))
            # print(i1 + i2)
            print(request.POST)
            print(request.body)
            return HttpResponse('...')
    

    3 上传文件

    • 基于原生Ajax XMLHttpRequest对象
    • JQuery Ajax
    • 伪Ajax

    app01.views.py

    import os
    def upload(request):
        if request.method == 'GET':
            return render(request, 'upload.html')
        else:
            print(request.POST, request.FILES)
            file_obj = request.FILES.get('fafafa')
            file_path = os.path.join('static', file_obj.name)
            print(file_path)
            with open(file_path, 'wb') as f:
                for chunk in file_obj.chunks():
                    f.write(chunk)
            return HttpResponse(file_path)
    

    templates.upload.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>原生Ajax上传文件</h1>
        <input type="file" id="i1">
        <a onclick="upload1();">上传文件</a>
        <div id="container1"></div>
    
        <h1>JQuery Ajax上传文件</h1>
        <input type="file" id="i2">
        <a onclick="upload2();">JQuery Ajax上传文件</a>
        <div id="container2"></div>
    
        <h1>伪Ajax上传文件</h1>
        <form id="f1" action="/upload/" method="post" target="ifr" enctype="multipart/form-data">
            <iframe id="ifr" name="ifr" style="display: none;"></iframe>
            <input type="file" id="i3" name="fafafa">
            <a onclick="upload3();">伪Ajax上传文件</a>
        </form>
        <div id="container3"></div>
    
        <script src="/static/jquery-3.2.1.min.js"></script>
        <script>
            function upload1() {
                var formData = new FormData();
                formData.append('k1', 'v1');
                formData.append('fafafa', document.getElementById('i1').files[0]);
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function(){
                    if(xhr.readyState == 4){
                        var  file_path = xhr.responseText;
                        var tag = document.createElement('img');
                        tag.src = "/"+ file_path;
                        document.getElementById('container1').appendChild(tag);
    
                    }
                };
                xhr.open('POST','/upload/');
                // xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                xhr.send(formData);
            }
            function upload2() {
                var formData = new FormData();
                formData.append('k1', 'v1');
                formData.append('fafafa', $('#i2')[0].files[0]);
    
                // DOM对象和JQuery对象的互换
                // $('#i2') -> $('#i2')[0]
                // document.getElementById('i1') -> $(document.getElementById('i1'))
                $.ajax({
                    url: '/upload/',
                    type: 'POST',
                    data: formData,
                    processData: false,  // 让原生的FormData做处理
                    contentType: false,  // 让原生的FormData做处理
                    success:function (arg) {
                        var tag = document.createElement('img');
                        tag.src = "/"+ arg;
                        $('#container2').append(tag)
                    }
                })
                
            }
            function  upload3() {
                document.getElementById('ifr').onload = loadIframe;
                document.getElementById('f1').submit();
            }
            function loadIframe() {
                var content = document.getElementById('ifr').contentWindow.document.body.innerText;
                var tag = document.createElement('img');
                tag.src = "/"+ content;
                $('#container3').append(tag)
            }
        </script>
    </body>
    </html>
    

    总结:

    伪Ajax兼容性更好(建议上传文件时使用),数据传输时建议使用JQuery
    

    4 JSONP技术

    4.1 Ajax存在的问题

    • 访问其他域名的URL会被阻止
    • 浏览器:
      • 同源策略,Ajax跨域发送请求时,再回来时浏览器拒绝接受
      • 允许script标签

    4.2 JSONP的本质

    templates.jsonp.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="/static/commons.js"></script>
    </head>
    <body>
    <a onclick="sendMsg();">发送</a>
    
    <script src="/static/jquery-3.2.1.min.js"></script>
    <script>
        function sendMsg() {
            // ajax会存在跨域问题
            /*
            $.ajax({
                url: 'http://dig.chouti.com/',
                type: 'GET',
                success:function (arg) {
                    console.log(arg)
                }
            })
            */
            // 报错:XMLHttpRequest cannot load http://dig.chouti.com/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8001' is therefore not allowed access.
            
            // JSONP
            var tag = document.createElement('script');
            tag.src = 'http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403';  // 返回list(数据)
            document.head.appendChild(tag); 
        }
    </script>
    
    </body>
    </html>
    

    /static/commons.js

    function list(arg) {
        console.log(arg);
    }
    
  • 相关阅读:
    android学习-仿Wifi模块实现
    爬虫4:cookie登陆并爬取学习成绩
    爬虫3:表单登陆
    爬虫2:爬取百度贴吧的帖子
    爬虫1:爬虫爬取糗事百科
    js中的typeof 操作符
    基于 Token 的身份验证方法
    Jfinal 列表分页
    百度地图逆地址解析
    Jfinal 项目搭建
  • 原文地址:https://www.cnblogs.com/wanyuetian/p/7152829.html
Copyright © 2020-2023  润新知