通过ajax方式向Django Post数据的方法

Django默认提供了很好的跨域攻击保护(csrf)机制,采用常规的方法,我们几乎感觉不到这个机制的存在(好吧,还是需要在form中添加{% csrf_token %})。但是当我们期望能够以Ajax的方式向服务器提交表单的时候,问题就来了。

常规的HTTP GET方法被认为是安全的,不会做csrf检查,而POST、PUT、DELETE等方法被认为是有潜在危险的。因为我们没有按照Django的要求在请求头/内容域中包含X-CSRFToken及相应的正确的值。Django会直接返回一个Http 403的错误回来。

解决的办法其实也很简单,就是按照要求提供这个值即可。在Django文档中有非常详细的描述(https://docs.djangoproject.com/en/1.4/ref/contrib/csrf/) ,也给除了一个非常简单的方法。

然而我们总不能将官方提供的代码到处粘贴吧,还是做一个简单的封装较好: 

 

/**
 * 自动设置Django的csrf请求.要求jquery > 1.5.1
 * 代码来自Django官网,做简单封装,直接引入此js即可.
 */
(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);
            }
        }
    });
})();

 

稍作解释:我们将官方提供的方法封装到一个匿名函数中,并通过在匿名函数外增加一对括号来强制js引擎将其视为一个表达式,返回值就是这个匿名函数,最后的一对括号则调用返回的这个匿名函数。

需要的时候只需要引入这个js即可。

posted @ 2012-09-12 14:03  雨吁的嘘  阅读(1444)  评论(0)    收藏  举报