Django中如何写Ajax请求及CSRF认证

  • Post author:
  • Post category:其他


最近下雨没有去学车,无聊在学习django,记录一下。两个内容:Ajax和csrf。是post请求就要进行csrf验证,get请求则就不需要。如果不清楚csrf_token的使用,就会遇到“django csrf token missing or incorrect”的错误。

一、Ajax请求

1.1 GET请求的Ajax

路由url.py配置:

## Django url.py 路由配置

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^add/',add),
    url(r'^home/$',index_home),
    url(r'^calculate/',post_form)
]

views.py渲染:

def post_form(request):
    return render(request,'index.html')

def add(request):
    if request.method == "POST":
        form = AddForms(request.POST)
        if form.is_valid():
            a = int(form.cleaned_data['a'])
            b = int(form.cleaned_data['b'])
            c = a + b
            return HttpResponse('post: %s + %s = (%s)'%(a,b,c))
    else:
        a = request.GET['a']
        b = request.GET['b']
        c = int(a) + int(b)
        return HttpResponse('get: %s + %s = (%s)'%(a,b,c))

模板index.html中传递数据给js

<!DOCTYPE html>
<html>
<body>
<p>计算数字之和</p>
<form action="/add/" method="get">
    a: <input type="text" id="numa" name="a"> <br>
    b: <input type="text" id="numb" name="b"> <br>
    <p>结果是: <span id='result'></span></p>
    <button type="button" id='sum'>求和</button>
</form>

<script src="http://apps.bdimg.com/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
    $(document).ready(function(){
      $("#sum").click(function(){
        var a = $("#numa").val();
        var b = $("#numb").val();

        $.get("/add/",{'a':a,'b':b}, function(ret){
            $('#result').html(ret)
        })
      });
    });
</script>
</body>
</html>

客户端效果为:

1.2 POST请求的Ajax

post请求这里涉及到csrf的校验,具体的过程可以拜读下csrf.js校验的代码,模板语言中需要加上如下代码:

$.ajaxSetup({
  data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});

将jQuery.get()变更为jQuery.post()方法,完整的模板index.html为:

<!DOCTYPE html>
<html>
<body>
<p>求两数字之和</p>
<form action="/add/" method="get">
    {% csrf_token %}
    a: <input type="text" id="numa" name="a"> <br>
    b: <input type="text" id="numb" name="b"> <br>
    <p>结果是: <span id='result'></span></p>
    <button type="button" id='sum'>求和</button>
</form>

<script src="/static/jquery.min.js"></script>

<script>

$.ajaxSetup({
  data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});

$(document).ready(function(){
      $("#sum").click(function(){
        var a = $("#numa").val();
        var b = $("#numb").val();

        $.post("/add/",{'a':a,'b':b}, function(ret){
            $('#result').html(ret)
        })
      });
    });
</script>
</body>
</html>

views.py和urls.py跟上面保持一致。

客户端效果为:

二、js代码

csrf.js代码为:

jQuery(document).ajaxSend(function(event, xhr, settings) {
    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;
    }
    function sameOrigin(url) {
        // url could be relative or scheme relative or absolute
        var host = document.location.host; // host + port
        var protocol = document.location.protocol;
        var sr_origin = '//' + host;
        var origin = protocol + sr_origin;
        // Allow absolute or scheme relative URLs to same origin
        return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
            (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
            // or any other URL that isn't scheme relative or absolute i.e relative.
            !(/^(\/\/|http:|https:).*/.test(url));
    }
    function safeMethod(method) {
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }

    if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
        xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
    }
});



版权声明:本文为weixin_39128119原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。