zoukankan      html  css  js  c++  java
  • django -- AJAX

    前戏

    AJAXAsynchronous Javascript And XML)翻译成中文就是异步的JavascriptXML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。

    AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

    AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)

    AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。

    • 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
    • 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。

    看个小栗子,页面输入两个整数,通过ajax返回后台,经过后台计算返回到页面

    html代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <input type="text" name="t1">+
        <input type="text" name="t2">=
        <input type="text" name="t3">=
        <button id="b1">结果</button>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
        <script>
            $('#b1').click(function () {
                $.ajax({
                    url:'/test/',
                    type:'post',
                    data:{
                        t1:$('[name="t1"]').val(),
                        t2:$('[name="t2"]').val()
                    },
                    success:function (res) {
                        $('[name="t3"]').val(res)
                    }
                })
            })
        </script>
    
    </body>
    </html>

    路由:

    url(r'^calc/', views.calc),
    url(r'^test/', views.test),

    视图

    def calc(request):
        return render(request, 'test.html')
    
    
    def test(request):
        print(request.POST.get('t1'), request.POST.get('t2'))
        i1 = int(request.POST.get('t1'))
        i2 = int(request.POST.get('t2'))
        i3 = i1 + i2
        return HttpResponse(i3)

    这样我们在页面输入两个整数,点击“结果”按钮就通过ajax发送到后台了,然后后台计算,在返回到页面

    AJAX的参数

    url: '/calc/',             # url地址
    type: 'post',              # 请求方式 
    data: {                    # 发送的数据  
            i1: $('[name="i1"]').val(),
            i2: $('[name="i2"]').val()
            hobby:JSON.stringify(['运维','开发','测试'])   # 传个列表  进行序列化
                        
                    },
                    success: function (res) {         # 回调函数   成功时调用  res 返回的内容
                        console.log(res);
                        $('[name="i3"]').val(res)
     
                    }

    AJAX处理csrf_token

    上面的例子,我们都是把csrf注释掉了,在实际的项目中肯定不能这么干,那还有其他的方法吗?

    方法一:通过获取隐藏的input标签中的csrfmiddlewaretoken值,放置在data中发送。只需要改htm<!DOCTYPE html>

    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        {% csrf_token %} 
        <input type="text" name="t1">+
        <input type="text" name="t2">=
        <input type="text" name="t3">=
        <button id="b1">结果</button>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
        <script>
            $('#b1').click(function () {
                $.ajax({
                    url:'/test/',
                    type:'post',
    data:{ t1:$(
    '[name="t1"]').val(), t2:$('[name="t2"]').val(), "csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val() // 使用jQuery取出csrfmiddlewaretoken的值,拼接到data中 }, success:function (res) { $('[name="t3"]').val(res) } }) }) </script> </body> </html>

    方法二:通过获取返回的cookie中的字符串 放置在请求头中发送。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        {% csrf_token %}
        <input type="text" name="t1">+
        <input type="text" name="t2">=
        <input type="text" name="t3">=
        <button id="b1">结果</button>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
        <script>
            $('#b1').click(function () {
                $.ajax({
                    url:'/test/',
                    type:'post',
                    headers: {"X-CSRFToken": $('[name="csrfmiddlewaretoken"]').val()},  // 从Cookie取csrftoken,并设置到请求头中
                    data:{
                        t1:$('[name="t1"]').val(),
                        t2:$('[name="t2"]').val()
    
                    },
                    success:function (res) {
                        $('[name="t3"]').val(res)
                    }
                })
            })
        </script>
    
    </body>
    </html>

    方法三:上面我们是给一个ajax设置,如果有多个,就要一一进行设置,我们可以统一进行设置

    我们需要有个js文件,首先去settings.py里设置静态文件

    STATIC_URL = '/static/'
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR, 'static')
    ]

    在static文件夹下创建一个js文件,写如下代码

    function getCookie(name) {
        var cookieValue = null;
        if (document.cookie && document.cookie !== '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
    var csrftoken = getCookie('csrftoken');
    
    
    function csrfSafeMethod(method) {
      // these HTTP methods do not require CSRF protection
      return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }
    
    $.ajaxSetup({
      beforeSend: function (xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
          xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
      }
    });

    最后再html文件里引入js文件就可以了

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <input type="text" name="t1">+
        <input type="text" name="t2">=
        <input type="text" name="t3">=
        <button id="b1">结果</button>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
        <script src="/static/ajax_setting.js"></script>
        <script>
            $('#b1').click(function () {
                $.ajax({
                    url:'/test/',
                    type:'post',
    
                    data:{
                        t1:$('[name="t1"]').val(),
                        t2:$('[name="t2"]').val()
    
                    },
                    success:function (res) {
                        $('[name="t3"]').val(res)
                    }
                })
            })
        </script>
    
    </body>
    </html>

    说明:使用第三种全局的设置,需要确保cookies中存在csrftoken值

    如果你的视图渲染的HTML文件中没有包含 {% csrf_token %},Django可能不会设置CSRFtoken的cookie。

    这个时候需要使用ensure_csrf_cookie()装饰器强制设置Cookie。

    from django.views.decorators.csrf import ensure_csrf_cookie
    
    @ensure_csrf_cookie
    def test(request):
        print(request.POST.get('t1'), request.POST.get('t2'))
        i1 = int(request.POST.get('t1'))
        i2 = int(request.POST.get('t2'))
        i3 = i1 + i2
        return HttpResponse(i3)

     AJAX上传文件

    html文件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        {% csrf_token %}
        <input type="file" id="my_file">
        <button id="b1">上传</button>
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
        <script src="/static/ajax_setting.js"></script>
        <script>
            $('#b1').click(function () {
                var form_obj = new FormData();
                form_obj.append('f1',$('#my_file')[0].files[0]);
                $.ajax({
                    url : '/upload/',
                    type : 'post',
                    data : form_obj,
                    processData : false,  // 告诉jQuery不要去处理发送的数据
                    contentType : false, // 告诉jQuery不要去设置Content-Type请求头
                    success:function (res) {
                        console.log(res)
                    }
                    }
    
                )
            })
        </script>
    </body>
    </html>

    视图函数

    def upload(request):
        if request.is_ajax():  # 判断是不是ajax请求
            f1 = request.FILES.get('f1')
            with open(f1.name, 'wb') as f:
                for i in f1.chunks():
                    f.write(i)
            return HttpResponse('上传成功')
        return render(request,'upload.html')
  • 相关阅读:
    jzoj 6278. 2019.8.5【NOIP提高组A】跳房子
    2019.08.05【NOIP提高组】模拟 A 组 总结
    HTML笔记
    html中的锚点设置
    前端HTML
    数据库设计(第一范式,第二范式,第三范式)
    MySQL之锁、事务、优化、OLAP、OLTP
    MySQL数据备份与还原(mysqldump)
    MySQl创建用户和授权
    MySQL之索引原理与慢查询优化
  • 原文地址:https://www.cnblogs.com/zouzou-busy/p/11257355.html
Copyright © 2011-2022 走看看