Nab Ilovich
Nab Ilovich

Reputation: 360

csrf token issue with multiple templates

I've got a template (index.html. It extends base.html) containing a form with a csrf_token which works good. I use JS/Ajax to send data to my view. So no problem with that.

The issue is that if I copy/paste my form to another template (for example : new.html which also extends base.html) I get : CSRF token missing or incorrect error. (HTTP 403 error in console)

Both templates use same JS function. The forms are exactly the same in both templates.

Any suggestion please?

Here the form (same in index.html and new.html) :

<form method="post" action="." enctype="multipart/form-data">
{% csrf_token %}
    <a href="#" class="heart pull-right" onclick="return Favorite(this)" data="foobar">
        <i class="fa fa-heart-o"></i>
    </a>
</form>

Here the JS/Ajax function :

function Favorite(item) {
    song_id = item.getAttribute("data"),
    $.ajax({
        type : "POST",
        datatype: "json",
        url: "/fav/",
        data: {
            'csrfmiddlewaretoken' : $('input[name=csrfmiddlewaretoken]').val(),
            song_id : song_id
        },
    });
    return false

By the way, the form in index.html is in a div. In new.html the form is in a table. Don't know if it helps.

Upvotes: 0

Views: 754

Answers (2)

Nab Ilovich
Nab Ilovich

Reputation: 360

I finally made it work (based on django doc and doniyor comments)

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;
}

function Favorite(item) {
  song_id = item.getAttribute("data-mp3"),
  csrftoken = getCookie('csrftoken');
  $.ajax({
    type : "POST",
    datatype: "json",
    url: "/fav/",
    data: {
      song_id : song_id
    },
    headers: {
      'X-CSRFToken': csrftoken
    }
  });
  return false;
}

Upvotes: 0

doniyor
doniyor

Reputation: 37904

first of all, you dont need <form> at all if you are sending the request with ajax.

secondly, you can set the csrf_token also in this way:

...
data: {
    csrfmiddlewaretoken: '{{ csrf_token }}',
    song_id : song_id
},
...

which always works for me.

Upvotes: 1

Related Questions