403 Forbidden and request.method showing GET in django

1.9k Views Asked by At

I am trying to send a form data to an app using AJAX.

Javascript part:

function submit_changes() {
var all_data = [A_list, B_list,C_list]
$.ajax({
    type: "POST",
    url: "/my_url/",
    contentType: "application/json",
    //dataType: 'json',
    //data:JSON.stringify(all_data),
data:{
    csrfmiddlewaretoken: "{{ csrf_token }}",        
    form:JSON.stringify(all_data),
},

  success: function() {
        alert('Data captured successfully');
        //window.location.reload();
    },
    error: function(){
        alert('Error in data capture')
        //window.location.reload();
    }
});
}

urls.py has this

urlpatterns=[url(r'^my_url/$',views.my_url_fn)]

views.py

def my_url_fn(request):
    print "*** request is ***",request
    if request.method == 'POST':
        print "request is POST"
        return Response(json.dumps(submit_changes(request)))
    elif request.method == 'GET':
        print "request is GET"
        return Response(json.dumps(get_already_present_data()),mimetype='application/json')
    else:
        print "neither post nor get"

Form part from html code is:

<div align="center">
  <form name="myForm" onSubmit="return 0">{% csrf_token %}    
    <input type="text" id="blah1" placeholder="Blah1&hellip;">
        <!-- few more fields -->
  </form> 
</div>
<div align='center'>
  <input id="submit_changes" type="button" align="middle" value="Submit Changes" onclick="submit_changes();" />
</div>

I have loaded the javascript in html. I am getting 403 forbidden error and the request.method is printing GET.

I have two things to ask :

1). Why is request.method GET when it is a POST request?

2). Why am I still getting 403 forbidden error even after giving csrf token?

I have searched a lot and tried these: Adding @csrf_exempt above my view and importing it as from django.views.decorators.csrf import csrf_exempt. No improvement. I have also tried removing django.middleware.csrf.CsrfViewMiddleware from MIDDLEWARE list in my settings.py. Still no progress! I have another question here. Does this mean changes in settings.py are not getting reflected ? Any help would be greatly appreciated !

2

There are 2 best solutions below

3
Shiv Shankar On BEST ANSWER

You can try this

<script type="text/javascript">

    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');
    $(document).ready(function () {
        $.ajax({
            type: 'post',
            url: "{% url "url_to_view" %}",
            headers: {"X-CSRFToken": csrftoken},
            data: {id: "something to view"},
            success: function (response) {
                alert("success");
                });
            },
            failure: function (response) {
                alert(response.d);
            }
        });
    });
</script>
0
Resley Rodrigues On

You need to do something like this in JavaScript to correctly set the csrf token. It doesn't need to part of the data, but rather the request headers

function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRF-Token", CSRF_TOKEN);
        }
    }
});

In django you don't need to do a csrf_exempt as the above code will inject the CSRF token into every ajax request, if needed. (there is a very good reason why CSRF is there so it's best not to exempt it)