Jquery and Django CSRF Token

Question:

I have 2 html Pages.

A Parent Page and a Child Page. The Child Page Contains a Submit Button that runs code on the Parent Page to submit an Ajax message.

I load the child page using $.load() method and then when the button is clicked it runs a $.ajax .POST Method. This post method only passes a JSON String to the Python Code.

When I do this on any browser except IE It works fine. However when I run this code in IE. I get Python / Django Errors about CSRF Tokens.

I Think the reason is because the child page is just a refresh of current page itself with the serverside code being run.

Does anyone know how I should go about getting this to work.

Cheers,

Asked By: TheMonkeyMan

||

Answers:

You are not passing the csrf token with POST. Try doing what I have done in data. That is to fetch the csrf token (or your own method) and pass it in your arguments.

$.ajax({
    url : url,
    type: "POST",
    data : {csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value},
    dataType : "json",
    success: function( data ){
        // do something
    }
});
Answered By: Zain Khan

From the docs on CSRF and AJAX:

The CSRF token is also present in the DOM, but only if explicitly included using csrf_token in a template. The cookie contains the canonical token; the CsrfViewMiddleware will prefer the cookie to the token in the DOM. Regardless, you’re guaranteed to have the cookie if the token is present in the DOM, so you should use the cookie!

Example (also from the docs)

// 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');

Or any other way of interacting with cookies could be used.

Answered By: Kevin

If you are sending a POST request body it maybe easier to add the csrf token as a request header instead. I find this approach easier to read, as it does not clutter up the request body with a token. Most AJAX request will send the csrf token as a header as suggested by the Django documentation.

function startTest(testId) {
  var payload = JSON.stringify({
    test_id : testId
  });
  $.ajax({
    url: "/test-service/",
    method: "POST",
    headers: {'X-CSRFToken': '{{ csrf_token }}'},
    data: payload,
    dataType: "json"
  }).done(function(response) {
    console.log(response.id + " " + response.name);
  }).fail(function (error) {
      console.log(error);
  });
}
Answered By: MichaelB
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.