Apostolos
Apostolos

Reputation: 8121

Django rest api using javascript client causing csrf issues on post requests

I am using this and this to post some data on my rest api. But I get a bad request (400) response.

A piece of my code

var dataTask = {};
var dataPeri = {};
var csrf;
var that = this;
var date = new Date();
var dateString;
dateString = date.toJSON().slice(0, 10);
dataPeri['date'] = dateString;
dataPeri['customer'] = customerId;
csrf = $('input[name="csrfmiddlewaretoken"]').val();
console.log('csrf:'+csrf);
console.log(dataPeri); //The objects seems fine with date at the right format and customerId a number
$.ajaxSetup({
   beforeSend: function(xhr, settings){
       if (!this.crossDomain){
           xhr.setRequestHeader("X-CSRFToken", csrf);
       }
   }
});
$.ajax({
    dataType:'json',
    type: 'post',
    url: '/crm/api/periodontogramms/',
    data:JSON.stringify(dataPeri),
    success: function (data, textStatus, jqXHR){
        alert("New Periodontogramm saved successfully");
        console.log("Periodontogramma "+ data);
        that.periodontogramms.push(data);
    },
    error: function (jqXHR, textStatus, errorThrown){
        alert(errorThrown);
    }
});

I cannot get what the error is because no other message comes with the error. I am sending Json back.(with JSON.stringify). Should I send something else? Could it be the dateString casuing the issue? On my browsable Api to post something I use date at the following format:YYY-MM-DD. That is what I get from the date.toJSON.slice(0, 10). If it was a csrf issue shouldn't I be getting a forbidden message(403)

Upvotes: 0

Views: 769

Answers (1)

Kevin Brown-Silva
Kevin Brown-Silva

Reputation: 41719

This was originally answered in the question by @Apostolos

It worked after I removed JSON.stringify and just sent plain javascript ojbect.

But there wasn't an explanation as to why. The problem is that you were sending the JSON data (encoded with JSON.stringify) as a string to the API, but the API was under the impression that you were sending form-encoded data.

You were using a few parameters in the $.ajax() call, but you were missing some important ones.

The dataType parameter tells jQuery what data type to expect back based on the Accept header that is being sent. In most cases, this is json, and by default jQuery will take an intelligent guess based on the contents of the response. It's usually right, but it doesn't hurt to help it.

The contentType parameter tells jQuery what data type is being sent to the server. By default this is application/x-www-form-urlencoded; charset=UTF-8, and when sending JSON data you must set this to application/json. This is important, as otherwise jQuery won't know what to do with the JSON string you've given it, and the API will have no idea what to do with the malformed form-encoded data.

The data parameter tells jQuery what data to send to the server. With the default contentType, this will accept a form-encoded string or a dictionary containing key -> value pairs that should be form-encoded. When the contentType is overridden, jQuery expects that the data sent here should match exactly what must be sent to the server, a JSON string in your case.


I would also recommend using your browser's developer tools to read the body of the response, as this should have told you there was a problem with the request you were sending in.

Upvotes: 1

Related Questions