简体   繁体   English

Django Rest Framwork中的“ PUT”请求Ajax中禁止403错误

[英]forbidden 403 error in 'PUT' request Ajax in django rest framwork

I am using django-rest framework while sending put ajax request got error 403 forbidden. 我正在使用django-rest框架,同时发送put ajax请求被禁止错误403。

user-details.html user-details.html

   <form action="{% url 'user-detail' pk=object.pk %}" id="use1">
        {% csrf_token %}
        {% for key,value in serializer.items %}
             {{key}} <input value="{{value}}" type="text" class="form-control" /><br>
        {% endfor %}

        <button class="btn btn-warning edit_record" type="button" >Update</button>
        <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#deleteModal">Delete</button>
    </form>

when I click on update button ajax will call and here I got formdata with hidden field csrftoken and also other parameters but after run this ajax i got 403 forbidden error however "DELETE" method working fine here. 当我单击更新按钮时,ajax将被调用,在这里,我得到了带有隐藏字段csrftoken和其他参数的formdata,但是在运行此ajax之后,我得到了403禁止错误,但是“ DELETE”方法在这里正常工作。

As far as I know we get this error when csrftoken is missing but I have csrf_token in my form. 据我所知,当csrftoken丢失但我的表单中有csrf_token时,我们会收到此错误。

$(".edit_record").on("click",function() {
        var url = document.location.pathname
        form = $(this).closest("form")[0],
        formData = new FormData(form);
         $.ajax({
             type:'PUT',
             url: url,
             data: formData,
             success: function (data) {

            },
              headers: {'X_METHODOVERRIDE': 'PUT'},

         });
    });

I used ModelViewset in views.py 我在views.py中使用了ModelViewset

 class UserViewSet(viewsets.ModelViewSet):
        queryset = User.objects.all()
        serializer_class = UserProfileSerializer

        def update(self, request, *args, **kwargs): 
            import pdb;pdb.set_trace() 
            response = super(UserViewSet, self).update(request, *args, **kwargs)
            success =  True if response.status_code in [200,201] else False
            return Response({'object':response.data, 'success':success})

        def partial_update(self, request, *args, **kwargs):
            import pdb;pdb.set_trace()

        def destroy(self, request,*args, **kwargs):   
            response = super(UserViewSet, self).destroy(request, *args, **kwargs)
            success =  True if response.status_code == 204 else False
            return Response({'data':success})

I think It is a Problem with Django Security and your Cookies. 我认为Django安全性和Cookie存在问题。 You need to configure your Middleware. 您需要配置中间件。 Please take a look at this SO solution and this piece of Django Documentation . 请看一下这个SO解决方案Django文档

What you could try is adding this to your Ajax Call and I would change the type to POST instead of PUT. 您可以尝试将其添加到Ajax Call中,然后将类型更改为POST而不是PUT。

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

What worked for me is implementing this into my JS: 对我有用的是将其实现到我的JS中:

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) {
   return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
    beforeSend: function(xhr, settings) {
       if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
           xhr.setRequestHeader("X-CSRFToken", csrftoken);
     }
  }
});

try this, 尝试这个,

    $.ajax({
        type:"DELETE",
        data:{},
        url:"{{ category_update }}",
        beforeSend:function(xhr){
            xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
        },
        success:function(data,textStatus){
            location.replace(location.href);
        },
        error:function(XMLHttpRequest, textStatus, errorThrown){
           document.write(XMLHttpRequest.responseText);
        }
    });

the point is : 重点是 :

beforeSend:function(xhr){
     xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
},

Thank you all for helping me but I got the solution by debug the dispatch method.Here I found that form data is missing that means there is invalid formdata in request. 谢谢大家的帮助,但我通过调试dispatch方法获得了解决方案。在这里,我发现表单数据丢失,这意味着请求中存在无效的formdata。 There is no issue of csrf_token but issue in parameters which sent to ajax request. 没有问题csrf_token,但是发送给ajax请求的参数问题。

In ajax currently i used - 在我目前使用的ajax中-

    form = $(this).closest("form")[0],
    formData = new FormData(form);

and send this formData in request( still now i Don't know why it is not working here while i always used this thing in django).I just replace the above code with following code. 并在请求中发送此formData(现在我仍然不知道为什么它在我一直在django中一直使用时不起作用)。我只是用以下代码替换了上面的代码。

   form = $(this).closest("form"),            
   formData  = form.serialize()

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

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