通过我的AJAX帖子,我可以使用一些帮助来遵守Django的CSRF保护机制。我遵循了这里的说明:

http://docs.djangoproject.com/en/dev/ref/contrib/csrf/

我已经复制了他们在该页面上的AJAX示例代码:

http://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax

我把一个警告打印getCookie('csrftoken')的内容之前的xhr。setRequestHeader调用,它确实被一些数据填充。我不确定如何验证令牌是正确的,但我被鼓励它正在寻找和发送一些东西。

但是Django仍然拒绝我的AJAX帖子。

这是我的JavaScript:

$.post("/memorize/", data, function (result) {
    if (result != "failure") {
        get_random_card();
    }
    else {
        alert("Failed to save card data.");
    }
});

下面是我从Django中看到的错误:

[23/Feb/2011 22:08:29] "POST / remember / HTTP/1.1" 403 2332

我肯定我遗漏了什么,也许很简单,但我不知道是什么。我在SO周围搜索了一下,看到了一些关于通过csrf_exempt装饰器关闭视图的CSRF检查的信息,但我发现那没什么吸引力。我已经尝试过了,它是有效的,但如果可能的话,我宁愿让我的POST以Django设计的方式工作。

为了以防有用,这里是我的视图正在做的事情的要点:

def myview(request):

    profile = request.user.profile

    if request.method == 'POST':
        """
        Process the post...
        """
        return HttpResponseRedirect('/memorize/')
    else: # request.method == 'GET'

        ajax = request.GET.has_key('ajax')

        """
        Some irrelevent code...
        """

        if ajax:
            response = HttpResponse()
            profile.get_stack_json(response)
            return response
        else:
            """
            Get data to send along with the content of the page.
            """

        return render_to_response('memorize/memorize.html',
                """ My data """
                context_instance=RequestContext(request))

谢谢你的回复!


当前回答

因为它没有在当前的答案中任何地方说明,如果你没有将js嵌入到你的模板中,最快的解决方案是:

设置<script type="text/javascript">窗口。CSRF_TOKEN = "{{CSRF_TOKEN}}";</script>在你的模板中引用script.js文件,然后将csrfmiddlewaretoken添加到你的js文件中的数据字典中:

$.ajax({
            type: 'POST',
            url: somepathname + "do_it/",
            data: {csrfmiddlewaretoken: window.CSRF_TOKEN},
            success: function() {
                console.log("Success!");
            }
        })

其他回答

如果你用$。Ajax函数,你可以简单地在数据体中添加CSRF令牌:

$.ajax({
    data: {
        somedata: 'somedata',
        moredata: 'moredata',
        csrfmiddlewaretoken: '{{ csrf_token }}'
    },

Non-jquery回答:

var csrfcookie = function() {
    var cookieValue = null,
        name = 'csrftoken';
    if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = cookies[i].trim();
            if (cookie.substring(0, name.length + 1) == (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
};

用法:

var request = new XMLHttpRequest();
request.open('POST', url, true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.setRequestHeader('X-CSRFToken', csrfcookie());
request.onload = callback;
request.send(data);

因为它没有在当前的答案中任何地方说明,如果你没有将js嵌入到你的模板中,最快的解决方案是:

设置<script type="text/javascript">窗口。CSRF_TOKEN = "{{CSRF_TOKEN}}";</script>在你的模板中引用script.js文件,然后将csrfmiddlewaretoken添加到你的js文件中的数据字典中:

$.ajax({
            type: 'POST',
            url: somepathname + "do_it/",
            data: {csrfmiddlewaretoken: window.CSRF_TOKEN},
            success: function() {
                console.log("Success!");
            }
        })

I've just encountered a bit different but similar situation. Not 100% sure if it'd be a resolution to your case, but I resolved the issue for Django 1.3 by setting a POST parameter 'csrfmiddlewaretoken' with the proper cookie value string which is usually returned within the form of your home HTML by Django's template system with '{% csrf_token %}' tag. I did not try on the older Django, just happened and resolved on Django1.3. My problem was that the first request submitted via Ajax from a form was successfully done but the second attempt from the exact same from failed, resulted in 403 state even though the header 'X-CSRFToken' is correctly placed with the CSRF token value as well as in the case of the first attempt. Hope this helps.

问候,

Hiro

将这一行添加到jQuery代码中:

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

和完成。