Django(七)Ajax请求中csrf验证

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/youand_me/article/details/78932331

前言


在web应用中都比较熟悉ajax请求,当然在Django中也可以通过ajax请求数据。有时候我们需要在不刷新的情况载入一些内容,如何用 Django 来实现 不刷新网页的情况下加载一些内容,ajax请求就能发挥作用了。


Ajax请求

get方法

  • 表单

当我们使用form表单时,在第一层demo下的templates中新建一个add.html文件,要使用表单就需在表单中包含一个或多个type=”submit”的按钮,当点击这些按钮的时候就会以method方法去请求action的路由:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form action="/add/" method="get">
            <p>请输入两个数字</p>
            <label for="a">a: </label><input type="number" id="a" name="a"> <br>
            <label for="b">b: </label><input type="number" id="b" name="b"> <br>
            <p>result: <span id='result'>{{ result }}</span></p>
            <button type="submit" id='submit'>提交</button>
        </form>
    </body>
</html>
  • ajax

当不使用表单的时候,就须用按钮的响应函数来请求数据,修改add.heml如下(以下介绍两种方式,一种是get函数,一种是ajax常用形式,任选一种):

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <p>请输入两个数字</p>
        <label for="a">a: </label><input type="number" id="a" name="a"> <br>
        <label for="b">b: </label><input type="number" id="b" name="b"> <br>
        <p>result: <span id='result'>{{ result }}</span></p>
        <button type="button" id='submit'>提交</button>

        <script src="http://apps.bdimg.com/libs/jquery/1.11.1/jquery.min.js"></script>
        <script>
            $(document).ready(function(){
                $("#submit").click(function(){
                    var a = $("#a").val();
                    var b = $("#b").val();
                    //通过get函数的方式,第一个参数是请求的url,第二个参数是提交的数据,第三个是请求成功的回调函数
                    $.get("/add/",{'a':a,'b':b}, function(data){
                        $('#result').html(data.result)
                    });
                    //通过ajax方式请求
                    $.ajax({
                        type:"get",
                        data: {'a':a,'b':b},
                        url: "/add/", //后台处理函数的url 这里用的是static url 需要与urls.py中的name一致,或者直接写http地址
                        cache: false,
                        dataType: "json",
                        success: function(data){
                            $('#result').html(data.result)
                        },
                        error: function(){
                            alert("false");
                        }
                    });
                });
            });
        </script>
    </body>
</html>

然后配置路由,打开第二层demo目录下的urls.py,添加如下一句:

url(r'^add/', views.add),

在login这个app下的views.py中添加一个add视图函数:

def add(request):
    context = {}
    if 'a' in request.GET:
        a = request.GET['a']
        b = request.GET['b']
        c = int(a) + int(b)
        context['result'] = c
        # 当使用表单请求方式的时候将下一行注释,由于表单是请求一整个页面,需用render返回页面,二ajax请求的是json数据,需要json的dump转换
        return HttpResponse(json.dumps({'result': c, }), content_type="application/json")
    return render(request, 'add.html', context)

启动项目,打开http://127.0.0.1:8000/add/ 链接,然后输入两个整数,点击提交就会返回两个数的和。注意再切换请求方式的时候需要清除浏览器的缓存,不然得不到正确结果。

post

  • 表单

修改上面创建的add.html文件,当使用表单的post请求的时候,必须在表单下添加{% csrf_token %},因为django对post请求有csrf验证,防止请求伪造:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <form action="/add/" method="post">
            {% csrf_token %}
            <p>请输入两个数字</p>
            <label for="a">a: </label><input type="number" id="a" name="a"> <br>
            <label for="b">b: </label><input type="number" id="b" name="b"> <br>
            <p>result: <span id='result'>{{ result }}</span></p>
            <button type="submit" id='submit'>提交</button>
        </form>
    </body>
</html>
  • ajax

当不使用表单的时候,就须用按钮的响应函数来请求数据,修改add.heml如下(以下介绍两种方式,一种是get函数,一种是ajax常用形式,任选一种):

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <p>请输入两个数字</p>
        <label for="a">a: </label><input type="number" id="a" name="a"> <br>
        <label for="b">b: </label><input type="number" id="b" name="b"> <br>
        <p>result: <span id='result'>{{ result }}</span></p>
        <button type="button" id='submit'>提交</button>

        <script src="http://apps.bdimg.com/libs/jquery/1.11.1/jquery.min.js"></script>
        <script>
            $(document).ready(function(){
                $("#submit").click(function(){

                    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({
                        crossDomain: false, // obviates need for sameOrigin test
                        beforeSend: function(xhr, settings) {
                            if (!csrfSafeMethod(settings.type)) {
                                xhr.setRequestHeader("X-CSRFToken", csrftoken);
                            }
                        }
                    });

                    var a = $("#a").val();
                    var b = $("#b").val();
                    //通过get函数的方式,第一个参数是请求的url,第二个参数是提交的数据,第三个是请求成功的回调函数
                    $.post("/add/",{'a':a,'b':b}, function(data){
                        $('#result').html(data.result)
                    });
                    //通过ajax方式请求
                    $.ajax({
                        type:"POST",
                        data: {'a':a,'b':b},
                        url: "/add/", //后台处理函数的url 这里用的是static url 需要与urls.py中的name一致,或者直接写http地址
                        cache: false,
                        dataType: "json",
                        success: function(data){
                            $('#result').html(data.result)
                        },
                        error: function(){
                            alert("false");
                        }
                    });
                });
            });
        </script>
    </body>
</html>

注意在响应函数中需要添加csrf_token在请求的表头,防止请求伪造,添加的代码如下:

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({
     crossDomain: false, // obviates need for sameOrigin test
     beforeSend: function(xhr, settings) {
         if (!csrfSafeMethod(settings.type)) {
             xhr.setRequestHeader("X-CSRFToken", csrftoken);
         }
     }
 });

路由配置不变,在login这个app下的views.py中修改add视图函数:

def add(request):
    context = {}
    if 'a' in request.POST:
        a = request.POST['a']
        b = request.POST['b']
        c = int(a) + int(b)
        context['result'] = c
        # 当使用表单请求方式的时候将下一行注释,由于表单是请求一整个页面,需用render返回页面,二ajax请求的是json数据,需要json的dump转换
        return HttpResponse(json.dumps({'result': c, }), content_type="application/json")
    return render(request, 'add.html', context)

和get方式同样的启动项目,打开http://127.0.0.1:8000/add/ 链接,然后输入两个整数,点击提交就会返回两个数的和。注意再切换请求方式的时候需要清除浏览器的缓存,不然得不到正确结果。

猜你喜欢

转载自blog.csdn.net/youand_me/article/details/78932331