简体   繁体   English

在 Django 中使用 AJAX POST 请求进行 CSRF 检查期间禁止 403

[英]Forbidden 403 during CSRF check with an AJAX POST request in Django

I can't fix the problem with CSRF check.我无法通过 CSRF 检查解决问题。 Could you please tell me what I need to do?你能告诉我我需要做什么吗? This is my function from views.py:这是我在 views.py 中的函数:

@login_required
def like_day(request):
if request.method == 'POST':
    if 'day_id' in request.POST:
        day_id = request.POST['day_id']
        if day_id:
            day = Day.objects.get(id=int(day_id))
            likes = day.likes + 1
            day.likes = likes
            day.save()
            return HttpResponse(likes)

This is AJAX request:这是 AJAX 请求:

$(document).ready( function(){
    $('#likes2').click(function(){
        var catid;
        protect
        catid = $(this).attr("data-catid");
        $.post('/friends_plans/like_day/', {day_id: catid}, function(data){
            $('#like_count').html(data);
            $('#likes2').hide();
        });
    });
});

I've tried to use @ensure_csrf_cookie decorator forthe function, but it didn't help.我曾尝试@ensure_csrf_cookie函数使用@ensure_csrf_cookie装饰器,但它没有帮助。 I've tried to add this to my code:我试图将其添加到我的代码中:

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

It didn't help either.它也没有帮助。 I've done as it is described in the documentation: https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/ but then there is a mistake $.cookie is not a function.我已经按照文档中的描述完成了: https : $.cookie但后来有一个错误$.cookie is not a function。 To cope with this problem I downloaded csrf cookie plugin to my static directory or add this to my template <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script> , but still the same mistake.为了解决这个问题,我将 csrf cookie 插件下载到我的静态目录或将其添加到我的模板<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script> ,但还是同样的错误。

You can add {% csrf_token %} template tag in your form or posting function the make posting , if you want to avoid the error you can use decorater @csrf_exempt您可以在您的表单或发布功能中添加 {% csrf_token %} 模板标签,如果您想避免错误,您可以使用装饰器@csrf_exempt

 from django.views.decorators.csrf import csrf_exempt
    @csrf_exempt
    def hello(request):
       if request.is_ajax():
          print "hello is working fine"

more details : https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/更多细节: https : //docs.djangoproject.com/en/1.7/ref/contrib/csrf/

To account for CSRF using ajax, try following the Django docs suggestion of aquiring the token via JS: https://docs.djangoproject.com/en/1.9/ref/csrf/#ajax要使用 ajax 解释 CSRF,请尝试按照 Django 文档建议通过 JS 获取令牌: https : //docs.djangoproject.com/en/1.9/ref/csrf/#ajax

Create a JS file called csrf.js using the following (assuming jQuery):使用以下内容(假设使用 jQuery)创建一个名为 csrf.js 的 JS 文件:

// using jQuery
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');

Include that JS file on the template containing your ajax JS.将该 JS 文件包含在包含 ajax JS 的模板中。

You should then be able to do what you need safely.然后,您应该能够安全地做您需要的事情。

I was also facing the same issue, but it got resolved.我也遇到了同样的问题,不过已经解决了。

Information: I had a basic contact form which makes POST request to Django View '/contact-form'.信息:我有一个基本的联系表格,它向 Django View '/contact-form' 发出 POST 请求。 But it was giving '403 Forbidden' error.但它给出了“403 Forbidden”错误。 The HTML is as follows: HTML如下:

<form method="post">
    {% csrf_token %}
    <input>...</input>
    <button id="contact-form" type="submit"> <span>Envoyer</span</button>
</form>

Reason: It says that the Django Url is protected by any forgery and you should include a CSRF token in you Ajax call.原因:它说 Django Url 受任何伪造保护,您应该在 Ajax 调用中包含 CSRF 令牌。

Solution: 1) Get CSRF token before making Ajax request like this:解决方案: 1)在发出 Ajax 请求之前获取 CSRF 令牌,如下所示:

var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();

2) And then include csrftoken in you Ajax request header like this: 2)然后在你的 Ajax 请求头中包含 csrftoken,如下所示:

        jQuery.ajax({
            type: "POST",
            url: "/contact-form/",
             headers: {
                'X-CSRFToken': csrftoken
           },
            data: data,
            success: function() {
                alert('success');
            }
        });

When you use csrfmiddlewaretoken in your templates you use {% csrf_token %} ie include in somewhere in your html body.当您在模板中使用 csrfmiddlewaretoken 时,您使用{% csrf_token %}即包含在您的 html 正文中的某处。 {% csrf_token %} is evaluated to {% csrf_token %} 被评估为

<input type="hidden" name="csrfmiddlewaretoken" value="somevalue">

You can then use jquery to lookup this particular hidden field and retrieve its value and pass it in your ajax call.然后,您可以使用 jquery 查找此特定隐藏字段并检索其值并将其传递到您的 ajax 调用中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM