【问题标题】:Forbidden 403 during CSRF check with an AJAX POST request in Django在 Django 中使用 AJAX POST 请求进行 CSRF 检查期间禁止 403
【发布时间】:2016-09-16 21:19:45
【问题描述】:

我无法解决 CSRF 检查的问题。你能告诉我我需要做什么吗? 这是来自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)

这是 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();
        });
    });
});

我尝试使用@ensure_csrf_cookie 装饰器来实现该功能,但没有帮助。我已尝试将此添加到我的代码中:

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

它也没有帮助。 我已经按照文档中的描述完成了:https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/ 但随后出现错误$.cookie is not a function。为了解决这个问题,我将 csrf cookie 插件下载到我的静态目录或将其添加到我的模板<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>,但仍然是同样的错误。

【问题讨论】:

    标签: ajax django cookies http-post django-csrf


    【解决方案1】:

    您可以在您的表单或发布功能中添加 {% 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"
    

    更多详情:https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/

    【讨论】:

      【解决方案2】:

      我也遇到了同样的问题,但是已经解决了。

      信息: 我有一个基本的联系表格,它向 Django View '/contact-form' 发出 POST 请求。但它给出了“403 Forbidden”错误。 HTML如下:

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

      原因:它说 Django Url 受到任何伪造的保护,您应该在 Ajax 调用中包含一个 CSRF 令牌。

      解决方案: 1) 在发出 Ajax 请求之前获取 CSRF 令牌,如下所示:

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

      2) 然后在你的 Ajax 请求标头中包含 csrftoken,如下所示:

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

      【讨论】:

        【解决方案3】:

        要考虑使用 ajax 的 CSRF,请尝试按照 Django 文档建议通过 JS 获取令牌:https://docs.djangoproject.com/en/1.9/ref/csrf/#ajax

        使用以下内容(假设为 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');
        

        包括 包含您的 ajax JS 的模板上的那个 JS 文件。

        你应该能够安全地做你需要做的事情。

        【讨论】:

          【解决方案4】:

          当您在模板中使用 csrfmiddlewaretoken 时,您会使用 {% csrf_token %},即包含在 html 正文中的某处。 {% csrf_token %} 被评估为

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

          然后您可以使用 jquery 来查找这个特定的隐藏字段并检索其值并将其传递给您的 ajax 调用。

          【讨论】:

            猜你喜欢
            • 2018-11-06
            • 2017-06-26
            • 1970-01-01
            • 2011-07-03
            • 2018-11-05
            • 2014-01-25
            • 2018-06-06
            • 1970-01-01
            相关资源
            最近更新 更多