Omid Shojaee
Omid Shojaee

Reputation: 347

CSRF token missing or incorrect with AJAX

I have followed this tutorial and defined my form as below:

    <form action="" id="contactForm" method="post" role="form" class="contact-form">
    {% csrf_token %}
    ...

views.py:

def contact(request):
    if request.is_ajax():
        sender_name = request.POST.get('sender_name')
        sender_email = request.POST.get('sender_email')
        message_subject = request.POST.get('message_subject')
        message_text = request.POST.get('message_text')

        html_message = render_to_string('contact.html', {'sender_name': sender_name, 'sender_email': sender_email, 'message_subject': message_subject, 'message_text': message_text})

        email_subject = 'Message Subject'
        email_from = 'My Name'
        email_to = ['[email protected]',]

        send_mail(email_subject, '', email_from, email_to, html_message=html_message)

        response = {}

        return JsonResponse(response)

AJAX code:

$('#contactForm').submit(function(e){
    e.preventDefault()

    $('#loading').css("display", "block")

    $.ajax({
        type : "POST",
        url : "/contact/",
        data: {
            sender_name : $('#name').val(),
            sender_email : $('#email').val(),
            message_subject : $('#subject').val(),
            message_text : $('#message').val(),
            csrfmiddlewaretoken : '{{ csrf_token }}',
            datatype : "json",
        },

        success: function(){
            $('#loading').css("display", "none"),
            $('#sent-message').css("display", "block")
        },
    });
});

However, I get the annoying "CSRF token missing or incorrect" error after submitting the form.

Please assist.

EDIT:

I moved the AJAX code from external JS file to the index.html and it worked! So it seems {% csrf_token %} is not available to my JS file. Why is that and how to solve it?

Upvotes: 2

Views: 754

Answers (3)

jackygab
jackygab

Reputation: 58

var el = document.getElementsByName("csrfmiddlewaretoken");
csrf_value = el[0].getAttribute("value");

then in your data

'csrfmiddlewaretoken' : csrf_value,

Upvotes: 1

Sachihiro
Sachihiro

Reputation: 1779

According to this from original Django docs, you need to implement the function getCokie(name) as:

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

And then you set the headers as:

$.ajaxSetup({
   headers:{
      'X-CSRFToken': getCookie("csrftoken")
   }
});

I was implementing it today, and it worked, I was using reactJs and was making the request by using XMLHttpRequest() but it should be very similar.

Upvotes: 2

opia austin
opia austin

Reputation: 74

have you tried attaching your csrf like this

To embed a csrf token in each AJAX request, for jQuery it may be:

$(function () {

   $.ajaxSetup({
      headers: { "X-CSRFToken": getCookie("csrftoken") }
   });

});

Upvotes: 0

Related Questions