Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QueryDict always empty from AJAX POST

I have seen a few of these questions asked but I have tried to implement their solutions and it hasn't worked for me.

I am trying to send a basic AJAX request to a django view using POST. Here is my JQuery:

$('#save-button').click(function() {
    var names = ['BLOGGS Joe', 'SMITH John'];
    data = JSON.stringify(names);
    $.ajax({
        "contentType": "application/json; charset=utf-8",
        "data": data,
        "url" : "/ajax/myteam/save/",
        "type": "POST",
        "success": function(response) {

        }
    });
});

And here is my Django view:

def myteam_save(request):
   if request.method == 'POST':
       if request.POST:
           print 'Hurray'
       else:
           print 'Boo'
       response = HttpResponse(json.dumps({'code':'ok'}), content_type='application/json')
       return response

When I examine whats happening in Firebug I see that the post is being made as I intend but the QueryDict object from request.POST is always empty.

I have been careful about csrf tokens I think and even tried turning off the 'django.middleware.csrf.CsrfViewMiddleware' in my settings but this appears to have no effect.

What am I doing wrong?

Thanks for your help!

like image 762
lac Avatar asked Sep 11 '14 15:09

lac


People also ask

What is difference between AJAX and POST?

post is a shorthand way of using $. ajax for POST requests, so there isn't a great deal of difference between using the two - they are both made possible using the same underlying code.

Is AJAX request GET or POST?

GET vs POST in AJAX callsUnless you are sending sensitive data to the server or calling scripts which are processing data on the server it is more common to use GET for AJAX calls. This is because when using XMLHttpRequest browsers implement POST as a two-step process (sending the headers first and then the data).

Why do we use processData in AJAX?

processData. If set to false it stops jQuery processing any of the data. In other words if processData is false jQuery simply sends whatever you specify as data in an Ajax request without any attempt to modify it by encoding as a query string.

How does AJAX POST work?

jQuery Ajax Post method, or shorthand, $. post() method makes asynchronous requests to the web server using the HTTP POST method and loads data from the server as the response in the form of HTML, XML, JSON, etc.


2 Answers

As @Sergio told, you need to decode the request.body in you views.py. This is the solution by using Django 3.1 and Fetch.

def myteam_save(request):
    if request.method == 'POST' and request.headers.get("contentType": "application/json"):
        body_unicode = request.body.decode('utf-8')
        received_json = json.loads(body_unicode)

    return JsonResponse(received_json, safe=False)

I am not familiar with AJAX. So I post how typical POST with XHR should be using Fetch. Assuming varKey and varValue is pre-defined variables with value to send as json:

According to official documentation you have to pass it for security reasons.

function getCookie(name) {
    let cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        const cookies = document.cookie.split(';');
        for (let i = 0; i < cookies.length; i++) {
            const cookie = cookies[i].trim();
            // 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;
}
const csrftoken = getCookie('csrftoken');

Below is actual XHR done by using Fetch:

dict = { [varKey]: varValue }

fetch("http://127.0.0.1:8000/bot/api/post/45/", {
    headers: {
        'X-CSRFToken': csrftoken,
        "x-Requested-With": "XMLHttpRequest",
        "Content-Type": "application/json"
    },
    method: 'POST',
    body: JSON.stringify(dict),
    mode: 'same-origin',
})
like image 90
Ulvi Avatar answered Oct 06 '22 01:10

Ulvi


Django doesn't really de-serialize JSON payloads for you. request.POST is meant to be used for HTML posted forms, and the like.

For JSON payloads, you should de-serialize the request body yourself, for example: json.loads(request.body).

(request.body is how you access the raw payload).

like image 32
Sergio Pulgarin Avatar answered Oct 06 '22 00:10

Sergio Pulgarin