Jquery and Django CSRF Token

2019-01-16 17:06发布

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,

3条回答
萌系小妹纸
2楼-- · 2019-01-16 17:17

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
    }
});
查看更多
小情绪 Triste *
3楼-- · 2019-01-16 17:29

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);
  });
}
查看更多
老娘就宠你
4楼-- · 2019-01-16 17:34

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.

查看更多
登录 后发表回答