• Django之Ajax提交


    Django之Ajax提交

      Ajax:提交数据,页面不刷新。Ajax要引入jQuery。

      Ajax 是基于异步JavaScript和XML创建的交互式页面应用技术。

        JS实现页面的跳转:

          location.href = "/url/"

     1 $ajax({
     2     url:'要提交的地址' 3     type:"POST",  #GET 或 POST 的提交方式
     4     data:{"k1":"v1","k2":"v2"},  #提交的数据
     5     success:function(data){
     6         #当前服务端处理完毕后,字典执行的回调函数
     7         #data返回的数据
     8         console.log(data);
     9         if (data=='ok'):
    10             location.href = "/url/"
    11         else:
    12             return HttpR......
    13     }
    14 })

      原生Ajax:

        原生Ajax 是用了一个浏览器的一个对象,这个对象是XMLHttpRequest。

          前端代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <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-1.12.4.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(){
                /*  GET请求
                var xhr = new XMLHttpRequest();    //新创建的对象,只有创建了对象,才有open等方法。
                xhr.onreadystatechange = function(){ //onreadystatechange是回调函数,只要状态发生变化,这个函数就会被执行
                    if(xhr.readyState == 4){   //定义等readyState的值为4时,在执行这个回调函数。
                        alert(xhr.responseText);  //responseText是服务端返回的内容
                    }
                };
                xhr.open('GET','/add2/?i1=12&i2=19');   //open里指定打开的方式。
                xhr.send();        //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");
            }
        </script>
    </body>
    </html>
    View Code

        后端代码:

    from django.shortcuts import render,HttpResponse
    
    def index(request):
        return render(request,'index.html')
    
    def add1(request):
        a1 = int(request.POST.get('i1'))
        a2 = int(request.POST.get('i2'))
        return HttpResponse(a1 + a2)
    
    def add2(request):
        if request.method == "GET":
            i1 = int(request.GET.get('i1'))
            i2 = int(request.GET.get('i2'))
            print('add2.....')
            return HttpResponse(i1+i2)
        else:
            print(request.POST)
            print(request.body)  #body里是请求体数据
            return HttpResponse('...')

        在原生ajax中,用GET请求发送数据是不用设置请求头的,但是在POST中,是要加上

        setRequestHeader('Content-Type','application/x-www-form-urlencoded') 的。

      伪Ajax:伪Ajax是不用XMLHttpRequest,他是用浏览器的特性,用标签和标签的特性来伪造的。

         在伪ajax中,就要说到iframe标签。

          在iframe标签中的src中定义的任何网址,都会完全将这个网址搬运过来。

          iframe 具有不刷新打开页面的功能。

          比如在我们的index页面中,访问我们的index,在页面标签中用iframe,src设置成百度的url,

          那么当我们访问index时,页面内容就是百度的内容。

          前端: 

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div>
            <input type="text" id="txt1" />   //input里输入的url,提交给onclick,onclick事件交给iframe去提交。
            <input type="button" value="查看" onclick="changeScr();"/>
        </div>
        <iframe id="ifr" style=" 1000px;height: 2000px;" src="http://www.baidu.com.cn"></iframe>
        <script>
            function changeScr(){
                var inp = document.getElementById('txt1').value;
                document.getElementById('ifr').src = inp;
            }
        </script>
    </body>
    </html>

        后端:   

    def baidu(request):
        return render(request,'baidu.html')  

        用form提交ifr,也可以做到页面不刷新:

          form是把数据打包发送,但页面刷新,可以form中加入iframe,也会使其页面不刷新并提交数据。

        后端:  

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

        前端:  

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <form id="f1" method="POST" action="/fake_ajax/" target="ifr"> //target是将原有的form提交方式交给ifr去提交。
            <iframe id="ifr" name="ifr" style="display: none"></iframe> //用iframe提交form的数据,style为none是将整个标签隐藏起来。iframe里面放的是页面的返回值。
                                                                        //iframe里面在有返回值时,会执行一个onload,表示加载了返回的数据。
            <input type="text" name="user" />
            <a onclick="submitForm();">提交</a>  //通过a标签提交onload
        </form>
        <script>
            function submitForm(){
                document.getElementById('ifr').onload = loadIframe;
                document.getElementById('f1').submit();  //通过js提交form表单
            }
            function loadIframe(){
                var content = document.getElementById('ifr').contentWindow.document.body.innerText; //通过回调的方式,取iframe的内容。
                alert(content);
            }
        </script>
    </body>
    </html>

      跨域Ajax:用JSONP。

         json是字符串,而jsonp是一个小技巧。

        用到jsonp是因为在ajax中,存在一些问题:

          ajax中的问题:

            ajax访问自己的域名url是没有问题的,但是如果ajax访问其他域名的url,ajax是报错的。

            其报错原因是浏览器的同源策略。

            一个正常的请求经过ajax提交,并拿到返回数据返回,但是如果ajax提交的数据的url是其他的url,那么前端是拿不到的。浏览器是阻止访问的。

            在这个流程中,客户的请求是发送到了服务器,并且服务器也返回了数据,只不过是浏览器给禁止的这个操作。

        浏览器的同源策略:

          在ajax跨域发送请求,并带有返回值返回时,浏览器是拒绝接受的。

        而jsonp就是弥补这个小缺陷的。

          jsonp是可以绕过浏览器的同源策略并拿到数据的

          浏览器阻止的是ajax的操作,但是并不能阻止scr属性的操作,比如script标签

          远程发请求,是要告诉对方我们的url是什么的。

          所以jsonp就是这么做的。  

        示例:向其他网站发Http请求,

         后端:

    def jsonp(request):
        return render(request,'jsonp.html')

        前端:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src="/static/commons.js"></script>
    </head>
    <body>
        <a onclick="sendMsg();">发送</a>
        <script>
            function sendMsg(){
                var tag = document.createElement('script');
                //发送端,把数据拼接成script,然后把script放在html中,给他创建一个对象,加在页面就可以发送这个请求啦
                tag.src = "http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403";  //这个url就是要跨域的。可以换成任何url。
                document.head.appendChild(tag);
            }
        </script>
    </body>
    </html>

        static的内容:commons.js

    function list(arg){
        console.log(arg);
    }

      API:

        API就是一个url,我们总说API是个接口,其实本质就是一个url,这个url带有数据发送给来的请求。

        S5的url向s4的url发送请求,并拿到s4的用户列表,

       流程是点击s5的发送按钮,发送ajax请求,发送到s4的url,拿到s4的用户列表,并显示在s5的页面中。

     

     

       实例:

        我们定义一个服务端,叫s4,用来接收请求,并返回请求数据:

         服务端的S4的的view。

    import json
    from django.shortcuts import render,HttpResponse
    from django.core.handlers.wsgi import WSGIRequest
    
    from django.views import View
    
    def users(request):
        v = request.GET.get('funcname')  #获取一个动态的变量名v
        print('请求来了...')
      #这个user_list就是s4要返回给s5的列表数据 user_list
    = [ 'alex','eric','egon' ] user_list_str = json.dumps(user_list) temp = "%s(%s)" %(v,user_list_str,) #将v的变量名赋予user_list的值,使其变量不会被当做是全局变量使用。 print(temp) return HttpResponse(temp) def new_users(request): print(request.method) if request.method == "OPTIONS": obj = HttpResponse() obj['Access-Control-Allow-Origin'] = "*" obj['Access-Control-Allow-Methods'] = "DELETE" return obj obj = HttpResponse('asdfasdf') obj['Access-Control-Allow-Origin'] = "*" return obj # user_list = [ # 'alex','eric','egon' # ] # user_list_str = json.dumps(user_list) # obj = HttpResponse(user_list_str) # # obj['Access-Control-Allow-Origin'] = "*" # return obj

        我们在S5的发送请求中,去访问S4,也既是一个跨域操作,用到了Jsonp的特性。

         s5的view

    def jsonp(request):
        # import requests
        # requests.get()
        # requests.post()
    
        return render(request,'jsonp.html')
    
    def cors(request):
        return render(request,'cors.html')

        S5的template 的前端代码:

     <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <input type="button" value="获取用户列表" onclick="getUsers();" />
        <ul id="user_list">
        </ul>
        <script src="/static/jquery-1.12.4.js"></script>
        <script>
            /*
            function getUsers(){
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function(){
                    if(xhr.readyState == 4){
                        var content = xhr.responseText;
                        console.log(content);
                    }
                };
                xhr.open('GET','http://www.s4.com:8001/users/');
                xhr.send();
            }
            */
            //a = ['alex','eric','egon']
    
            /*
             function getUsers(){
                 var tag = document.createElement('script');
                tag.src = "http://www.s4.com:8001/users/?funcname=bbb?sdd";
                document.head.appendChild(tag);
             }
    
            function bbb(arg){
                console.log(arg);
            }
            */
            function getUsers(){
                // XMLHttpRequest
                /*
                $.ajax({
                    url: 'http://www.s4.com:8001/users/?funcname=bbb',
                    type: 'GET',
                    success:function(arg){
                        console.log(arg);
                    }
                })
                */
                // JSONP
                $.ajax({
                    url: 'http://www.s4.com:8001/users/',
                    type: 'POST',
                    dataType: 'JSONP',
                    jsonp: 'funcname',
                    jsonpCallback: 'bbb'
                })
            }
    
            function bbb(arg){
                console.log(arg);
            }
        </script>
    </body>
    </html>

       JSONP只能发GET请求。 

       参考:articles/5703697.html

    ------- END ------

  • 相关阅读:
    Django 部署到Nginx
    Django 初识
    openstack操作之二 restful api
    openstack操作之一 命令行
    虚拟机创建流程中neutron代码分析(三)
    虚拟机创建流程中neutron代码分析(二)
    虚拟机创建流程中neutron代码分析(一)
    nova创建虚拟机源码分析系列之八 compute创建虚机
    nova创建虚拟机源码分析系列之七 传入参数转换成内部id
    Mysql之索引(六)
  • 原文地址:https://www.cnblogs.com/george92/p/8489117.html
Copyright © 2020-2023  润新知