zoukankan      html  css  js  c++  java
  • 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);
    }
    
  • 相关阅读:
    70.BOM
    69.捕获错误try catch
    68.键盘事件
    523. Continuous Subarray Sum
    901. Online Stock Span
    547. Friend Circles
    162. Find Peak Element
    1008. Construct Binary Search Tree from Preorder Traversal
    889. Construct Binary Tree from Preorder and Postorder Traversal
    106. Construct Binary Tree from Inorder and Postorder Traversal
  • 原文地址:https://www.cnblogs.com/wanyuetian/p/7152829.html
Copyright © 2011-2022 走看看