zoukankan      html  css  js  c++  java
  • Python学习笔记整理总结【Django】Ajax

     一、Ajax(part1)

      Ajax即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术,AJAX = 异步 JavaScript和XML(标准通用标记语言的子集),AJAX 是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。传统的网页(不使用 AJAX)如果需要更新内容,必须重载整个网页页面。

    1、初识

     1 $.ajax({
     2     url: '/host',               # 数据提交地址
     3     type: "POST",               # 提交类型
     4     data: {'k1': 123, 'k2': "root"},        # 提交的内容 字典格式
     5     success: function(data){    # 客户端会一直等待服务端返回的数值
     6             # data是服务器端返回的字符串
     7         var obj = JSON.parse(data);
     8     }
     9 })
    10  
    11 # 建议:永远让服务器端返回一个字典
    12 return HttpResponse(json.dumps(字典))

    2、简单的前后端交互

     <div class="shade hide"></div>
            <div class="add-modal hide">
                <form method="POST" action="/home/">
                <div class="group">
                    <input id='host' type="text" placeholder="主机名" name="hostname" />
                </div>
    
                <div class="group">
                    <input id='ip' type="text" placeholder="IP" name="ip" />
                </div>
    
                <div class="group">
                    <input id='port' type="text" placeholder="端口" name="port" />
                </div>
    
                <div class="group">
                    <select id='sel' name="b_id">
                        {% for op in b_list %}
                        <option value="{{ op.id }}">{{ op.caption }}</option>
                        {% endfor %}
                    </select>
                </div>
                <input type="submit" value="提交" />
                <a id="ajax_submit">要上天提交</a>
                <input id="cancel" type="button" value="取消" />
    
            </form>
    
        </div>
    #index.html
    $(function(){
        $('#ajax_submit').click(function () {
            $.ajax({
                url:"/test_ajax/",
                type:"POST",
                data:{'hostname':$('#host').val(),'ip':$('#ip').val(),'port':$('#port').val(),'b_id':$('#sel').val()},
                success:function (data) {
                    if(data=='OK'){
                        location.reload()   // 重新加载页面
                    }else {
                        alert(data);
                    }
                }
            })
        })
    })
    #Ajax代码
    def test_ajax(request):
        print(request.method)
        h = request.POST.get('hostname')
        i = request.POST.get('ip')
        p = request.POST.get('port')
        b = request.POST.get('b_id')
        print(h,i,p,b)
        if h and len(h) > 5:        # 主机名长度判断
            models.Host.objects.create(hostname=h,ip=i,port=p,b_id=b) # 创建数据
            return HttpResponse("OK")    # 返回OK 严格大小写
        else:
            return HttpResponse("主机名太短")  # 返回错误提示
    #Django代码

    3、对前后端交互完善(当后端有问题时,前端收不到data,页面无反应)

    <div class="add-modal hide">
                <form method="POST" action="/home/">
                <div class="group">
                    <input id='host' type="text" placeholder="主机名" name="hostname" />
                </div>
    
                <div class="group">
                    <input id='ip' type="text" placeholder="IP" name="ip" />
                </div>
    
                <div class="group">
                    <input id='port' type="text" placeholder="端口" name="port" />
                </div>
    
                <div class="group">
                    <select id='sel' name="b_id">
                        {% for op in b_list %}
                        <option value="{{ op.id }}">{{ op.caption }}</option>
                        {% endfor %}
                    </select>
                </div>
                <input type="submit" value="提交" />
                <a id="ajax_submit">要上天提交</a>
                <input id="cancel" type="button" value="取消" />
                <span id="error_msg"></span>
    
            </form>
    
        </div>
    #index.html
    $(function(){
        $('#ajax_submit').click(function () {
            $.ajax({
                url:"/test_ajax/",
                type:"POST",
                data:{'hostname':$('#host').val(),'ip':$('#ip').val(),'port':$('#port').val(),'b_id':$('#sel').val()},
                success:function (data) {
                    console.log(data)    // data {"data": null, "status": false, "error": "u4e3bu673au540du592au77ed"}
                    var obj = JSON.parse(data);     // 反序列化 把字符串data换成对象obj
                                                    // 序列化 JSON.stringify() 把obj转换为字符串
                    if(obj.status){
                        location.reload()   // 重新加载页面
                    }else {
                        $('#error_msg').text(obj.error)
                    }
                }
            })
        })
    })
    #Ajax代码
    import json
    def test_ajax(request):
        ret = {'status':True,'error':None,'data':None}  # 返回一个字典
        try:
            h = request.POST.get('hostname')
            i = request.POST.get('ip')
            p = request.POST.get('port')
            b = request.POST.get('b_id')
            print(h,i,p,b)
            if h and len(h) > 5:        # 主机名长度
                print("ok")
                models.Host.objects.create(hostname=h,ip=i,port=p,b_id=b)
            else:
                ret['status'] = False
                ret['error'] = '主机名太短'
        except Exception as e:
            ret['status'] = False
            ret['error'] = '请求错误'
        return  HttpResponse(json.dumps(ret))       # 对字典进行序列化
    #Django代码

    4、serialize自动获取表单数据

    <form class="add-form" method="POST" action="/home/">
                <div class="group">
                    <input id='host' type="text" placeholder="主机名" name="hostname" />
                </div>
    
                <div class="group">
                    <input id='ip' type="text" placeholder="IP" name="ip" />
                </div>
    
                <div class="group">
                    <input id='port' type="text" placeholder="端口" name="port" />
                </div>
    
                <div class="group">
                    <select id='sel' name="b_id">
                        {% for op in b_list %}
                        <option value="{{ op.id }}">{{ op.caption }}</option>
                        {% endfor %}
                    </select>
                </div>
                <input type="submit" value="提交" />
                <a id="ajax_submit">要上天提交</a>
                <input id="cancel" type="button" value="取消" />
                <span id="error_msg"></span>
    
            </form>
    #index.html
    $.ajax({
        url:"/test_ajax/",
        type:"POST",        
        data:$('.add-form').serialize(),  // 获取表单数据提交 必须是form表单
        success:function (data) {
            })
    #Ajax代码

    5、Ajax代码补充(traditional,dataType)

    $(function(){
        $('#add_submit_ajax').click(function(){
            $.ajax({
                url: '/ajax_add_app',
                data: {'user': 123,'host_list': [1,2,3,4]},
                // data: $('#add_form').serialize(),
                type: "POST",
                dataType: 'JSON',       // 内部对传过来的数据直接执行JSON.parse 拿到的数据直接为对象而非字符串
                traditional: true,      // 添加此项 当字典里包含列表时候,后端可以getlist到里面的数据
                success: function(obj){
                    console.log(obj);
                },
                error: function () {     // 未知错误时执行,指前端收不到后台发送的obj时,执行
                }
            })
        });
    })
    #Ajax代码
    def ajax_add_app(request):
        ret = {'status':True, 'error':None, 'data': None}
     
        app_name = request.POST.get('app_name')
        host_list = request.POST.getlist('host_list')
        obj = models.Application.objects.create(name=app_name)
        obj.r.add(*host_list)
        return HttpResponse(json.dumps(ret))
    #Django代码

    6、页面跳转和刷新

    $.ajax({
        url: '/index/',
        data: {'k': 'v', 'list': [1,2,3,4], 'k3': JSON.stringfy({'k1': 'v'}))}, $(form对象).serilize()
        type: 'POST',
        dataType: 'JSON':
        traditional: true,
        success:function(d){
            location.reload()              # 刷新
            location.href = "某个地址"     # 跳转
        }
    })
    View Code

    二、 Ajax(part2)

    原生Ajax、JQuery、伪Ajax三种方式使用优先级:

      如果发送的是【普通数据】: jQuery > XMLHttpRequest > iframe
      如果发送的是【文件】 :      iframe > jQuery(FormData) > XMLHttpRequest(FormData)

    ①原生Ajax操作
    Ajax主要就是使用 【XmlHttpRequest】对象来完成请求的操作,该对象在主流浏览器中均存在(除早起的IE),Ajax首次出现IE5.5中存在(ActiveX控件)
    1、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()
     
        终止请求
    #主要方法
    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...
    #主要属性

    2、用原生Ajax做个请求

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <input type="text"/>
        <input type="button" value="Ajax1" onclick="Ajax1();" />
     
        <script>
            function Ajax1(){
                var xhr = new XMLHttpRequest();
                xhr.open('POST', '/ajax_json/',true);
                xhr.onreadystatechange = function(){
                    if(xhr.readyState == 4){
                        // 接收完毕
                        var obj = JSON.parse(xhr.responseText);
                        console.log(obj);
                    }
                };
                xhr.setRequestHeader('k1','v1');
                // post请求必须加下面这句请求头 不然后台数据拿不到
                xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
                xhr.send("name=root;pwd=123");
            }
        </script>
    </body>
    </html>
    #HTML文件
    def ajax(request):
        return render(request,'ajax.html')
     
    def ajax_json(request):
        print(request.POST)
        ret = {'code':True,'data':None}
        import json
        return HttpResponse(json.dumps(ret))
    #views文件

    3、跨浏览器支持
    XmlHttpRequest(IE7+, Firefox, Chrome, Opera, etc.)
    ActiveXObject("Microsoft.XMLHTTP")(IE6, IE5)

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    
        <h1>XMLHttpRequest - Ajax请求</h1>
        <input type="button" onclick="XmlGetRequest();" value="Get发送请求" />
        <input type="button" onclick="XmlPostRequest();" value="Post发送请求" />
    
        <script src="/statics/jquery-1.12.4.js"></script>
        <script type="text/javascript">
    
            function GetXHR(){
                var xhr = null;
                if(XMLHttpRequest){
                    xhr = new XMLHttpRequest();
                }else{
                    xhr = new ActiveXObject("Microsoft.XMLHTTP");
                }
                return xhr;
    
            }
    
            function XhrPostRequest(){
                var xhr = GetXHR();
                // 定义回调函数
                xhr.onreadystatechange = function(){
                    if(xhr.readyState == 4){
                        // 已经接收到全部响应数据,执行以下操作
                        var data = xhr.responseText;
                        console.log(data);
                    }
                };
                // 指定连接方式和地址----文件方式
                xhr.open('POST', "/test/", true);
                // 设置请求头
                xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
                // 发送请求
                xhr.send('n1=1;n2=2;');
            }
    
            function XhrGetRequest(){
                var xhr = GetXHR();
                // 定义回调函数
                xhr.onreadystatechange = function(){
                    if(xhr.readyState == 4){
                        // 已经接收到全部响应数据,执行以下操作
                        var data = xhr.responseText;
                        console.log(data);
                    }
                };
                // 指定连接方式和地址----文件方式
                xhr.open('get', "/test/", true);
                // 发送请求
                xhr.send();
            }
    
        </script>
    
    </body>
    </html>
    #基于原生AJAX - Demo

    ②“伪”AJAX
    由于HTML标签的iframe标签具有局部加载内容的特性,所以可以使用其来伪造Ajax请求,进行偷偷的发送请求

    def ajax(request):
        return render(request,'ajax.html')
    
    def ajax_json(request):
        print(request.POST)
        ret = {'code':True,'data':None}
        import json
        return HttpResponse(json.dumps(ret))
    #处理文件

    1.Form表单提交到iframe中,页面不刷新

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <input type="text"/>
        <input type="button" value="Ajax1" onclick="Ajax1();" />
     
        <form action="/ajax_json/" method="POST" target="ifm1"> <!-- target跟iframe进行关联 -->
            <iframe id="ifm1" name="ifm1" ></iframe>
            <input type="text" name="username" />
            <input type="text" name="email" />
            <input type="submit" value="Form提交"/>
        </form>
    </body>
    </html>
    View Code

    2.Ajax提交到iframe中,页面不刷新

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <input type="text"/>
        <input type="button" value="Ajax1" onclick="Ajax1();" />
     
        <input type='text' id="url" />
        <input type="button" value="发送Iframe请求" onclick="iframeRequest();" />
        <iframe id="ifm" src="http://www.baidu.com"></iframe>
     
        <script src="/static/jquery-1.12.4.js"></script>
        <script>
     
            function iframeRequest(){
                var url = $('#url').val();
                $('#ifm').attr('src',url);
            }
        </script>
    </body>
    </html>
    View Code

    3.Form表单提交到iframe中,并拿到iframe中的数据

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <input type="text"/>
        <input type="button" value="Ajax1" onclick="Ajax1();" />
     
        <form action="/ajax_json/" method="POST" target="ifm1">
            <iframe id="ifm1" name="ifm1" ></iframe>
            <input type="text" name="username" />
            <input type="text" name="email" />
            <input type="submit" onclick="sumitForm();" value="Form提交"/>
        </form>
     
        <script type="text/javascript" src="/static/jquery-1.12.4.js"></script>
        <script>
            function sumitForm(){
                $('#ifm1').load(function(){
                    var text = $('#ifm1').contents().find('body').text();
                    var obj = JSON.parse(text);
                    console.log(obj)
                })
            }
        </script>
    </body>
    </html>
    View Code

    三、XmlHttpRequest、JQuery、Iframe进行文件上传 

    def upload(request):
        return render(request,'upload.html')
    
    
    def upload_file(request):
        username = request.POST.get(('username'))
        fafafa = request.FILES.get('fafafa')        #获取文件
    
        with open(fafafa.name,'wb') as f:
            for item in fafafa.chunks():
                f.write(item)
        print(username,fafafa)
        ret = {'code': True, 'data': request.POST.get('username')}
        import json
    
        return HttpResponse(json.dumps(ret))
    #处理文件

    ① 原生Ajax(XmlHttpRequest)上传文件+定制好看的上传按钮

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            .upload{
                display: inline-block;padding: 10px;
                background-color: brown;
                position: absolute;
                top: 0;
                bottom: 0;
                right: 0;
                left: 0;
                z-index: 90;
            }
            .file{
                width: 100px;height: 50px;opacity: 0;
                position: absolute;
                top: 0;
                bottom: 0;
                right: 0;
                left: 0;
                z-index: 100;
            }
        </style>
    </head>
    <body>
        <div style="position: relative; 100px;height: 50px;">
            <input class="file" type="file" id="fafafa" name="afafaf" />
            <a class="upload">上传</a>
        </div>
        <input type="button" value="提交XHR" onclick="xhrSubmit();" />
         
        <script>
            function xhrSubmit(){
                // $('#fafafa')[0]
                var file_obj = document.getElementById('fafafa').files[0];  //获取文件对象
     
                var fd = new FormData();       
                fd.append('username','root');
                fd.append('fafafa',file_obj);
     
                var xhr = new XMLHttpRequest();
                xhr.open('POST', '/upload_file/',true);
                xhr.onreadystatechange = function(){
                    if(xhr.readyState == 4){
                        // 接收完毕
                        var obj = JSON.parse(xhr.responseText);
                        console.log(obj);
                    }
                };
                xhr.send(fd);
            }
        </script>
    </body>
    </html>
    View Code

    ② JQuery进行文件的上传

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            .upload{
                display: inline-block;padding: 10px;
                background-color: brown;
                position: absolute;
                top: 0;
                bottom: 0;
                right: 0;
                left: 0;
                z-index: 90;
            }
            .file{
                width: 100px;height: 50px;opacity: 0;
                position: absolute;
                top: 0;
                bottom: 0;
                right: 0;
                left: 0;
                z-index: 100;
            }
        </style>
    </head>
    <body>
        <div style="position: relative; 100px;height: 50px;">
            <input class="file" type="file" id="fafafa" name="afafaf" />
            <a class="upload">上传</a>
        </div>
    {#    <input type="button" value="提交XHR" onclick="xhrSubmit();" />#}
        <input type="button" value="提交jQuery" onclick="jqSubmit();" />
        <div id="preview"></div>
         
        <script src="/static/jquery-1.12.4.js"></script>
        <script>
            function jqSubmit(){
                // $('#fafafa')[0]
                var file_obj = document.getElementById('fafafa').files[0];
     
                var fd = new FormData();
                fd.append('username','root');
                fd.append('fafafa',file_obj);
     
                $.ajax({
                    url: '/upload_file/',
                    type: 'POST',
                    data: fd,
                    processData: false,  // tell jQuery not to process the data
                    contentType: false,  // tell jQuery not to set contentType
                    success:function(arg,a1,a2){
                        console.log(arg);
                        console.log(a1);
                        console.log(a2);
    // Object {readyState: 4, responseText: "{"data": "root", "code": true}", status: 200, statusText: "OK"}
                    }
                })
            }
        </script>
    </body>
    </html>
    View Code

    上面两种方式都用到FormData(),但是如果是IE浏览器的话是不支持FormData(),所以就得用到下面这种方式。
    ③ Iframe进行文件的上传

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <form id="form1" action="/upload_file/" method="POST" enctype="multipart/form-data" target="ifm1">
            <iframe id="ifm1" name="ifm1" style="display: none;"></iframe>
            <input type="file" name="fafafa"  />
            <input type="submit" onclick="iframeSubmit();" value="Form提交"/>
        </form>
        <script src="/static/jquery-1.12.4.js"></script>
        <script>
            function iframeSubmit(){
                $('#ifm1').load(function(){
                    var text = $('#ifm1').contents().find('body').text();
                    var obj = JSON.parse(text);
                    console.log(obj)
                })
            }
        </script>
    </body>
    </html>
    View Code

    四、上传文件时图片预览 

    ① 点击上传文件提交

    def upload(request):
        return render(request,'upload.html')
     
     
    def upload_file(request):
        username = request.POST.get(('username'))
        fafafa = request.FILES.get('fafafa')        #获取文件
        import os
        img_path = os.path.join('static/imgs/',fafafa.name)     #static下创建imgs目录
        with open(img_path,'wb') as f:
            for item in fafafa.chunks():
                f.write(item)
        print(username,fafafa)
        ret = {'code': True, 'data': img_path}
        import json
     
        return HttpResponse(json.dumps(ret))
    #处理文件
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <form id="form1" action="/upload_file/" method="POST" enctype="multipart/form-data" target="ifm1">
            <iframe id="ifm1" name="ifm1" style="display: none;"></iframe>
            <input type="file" name="fafafa"  />
            <input type="submit" onclick="iframeSubmit();" value="Form提交"/>
        </form>
        <div id="preview"></div>
        <script src="/static/jquery-1.12.4.js"></script>
        <script>
            function iframeSubmit(){
                $('#ifm1').load(function(){
                    var text = $('#ifm1').contents().find('body').text();
                    var obj = JSON.parse(text);
                    console.log(obj)
     
                     $('#preview').empty();
                    var imgTag = document.createElement('img');
                    imgTag.src = "/" + obj.data;
                    $('#preview').append(imgTag);
                })
            }
        </script>
    </body>
    </html>
    #HTML文件

    ② 选择文件后,直接上传

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <form id="form1" action="/upload_file/" method="POST" enctype="multipart/form-data" target="ifm1">
            <iframe id="ifm1" name="ifm1" style="display: none;"></iframe>
            <input type="file" name="fafafa" onchange="changeUpalod();" />    //onchange 选中文件时触发
    {#        <input type="submit" onclick="iframeSubmit();" value="Form提交"/>#}
        </form>
        <div id="preview"></div>
        <script src="/static/jquery-1.12.4.js"></script>
        <script>
            function changeUpalod(){
                $('#ifm1').load(function(){                //load  绑定load事件,有数据时执行
                    var text = $('#ifm1').contents().find('body').text();
                    var obj = JSON.parse(text);
     
                    $('#preview').empty();
                    var imgTag = document.createElement('img');
                    imgTag.src = "/" + obj.data;
                    $('#preview').append(imgTag);
                });
                $('#form1').submit();
            }
        </script>
    </body>
    </html>
    #HTML文件
  • 相关阅读:
    SQL SERVER中如何用SQL语句给表的栏位加注释sp_addextendedpropert
    baidu搜索出现错误提示页面
    ASP.NET MVC V2 Preview 1 发布 期望VS有更好的表现
    业务逻辑层实现事务处理
    FCKEidtor自動統計輸入字符個數(IE)
    Asp.Net 关于Could not load file or assembly 'Microsoft.Office.Interop.Excel, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' or one of its dependencies.问题的解决方法。
    Jquery Tabs 在asp.net 中的应用
    IBM总架构师寇卫东:话说程序员的职业生涯
    我喜欢的15个WordPress插件<转>
    The SqlParameter is already contained by another SqlParameterCollection.
  • 原文地址:https://www.cnblogs.com/liwei1153300111/p/8391270.html
Copyright © 2011-2022 走看看