1

I have this part of code:

document.querySelector('#form_pizza_order').onsubmit = () => {

    // make an ajax request to save the pizza order in the server
   const request = new XMLHttpRequest();
   request.open('POST', '/order_pizza');

   // Callback function for when request completes
   request.onload = () => {
       const data = JSON.parse(request.responseText);

       if (data.success) {
        // show in cart new order
        show_in_cart(data);
       }
       else {
           alert('failed to save pizza order in server');
       }
   }

   const data = new FormData();
   let username = localStorage.getItem('username');
   data.append('username', username);

   //Send request
   request.send(data);
   return false;
};

that when used the server returns 403 forbidden response because of csrf_token not sent. how do I add the crsf_token header properly with the javascript above, without using jquery. just javascript.

thanks.

2 Answers 2

1
function sendData(){
    const XHR = new XMLHttpRequest();
    // Set up our request
    XHR.open("POST", "{% url 'test:index' %}" );
    XHR.setRequestHeader('X-Requested-With', 'XMLHttpRequest')
    // Bind the FormData object and the form element
    let FD = new FormData(form);
    // append the token
    FD.append('csrfmiddlewaretoken', '{{ csrf_token }}');
    // The data sent is what the user provided in the form
    XHR.send(FD);
}

let form = document.getElementById('<form_id>')

//  take over its submit event.
form.addEventListener("submit", function (event) {
    console.log('Submited!')
    event.preventDefault();
    sendData();
})

In your django views, you can test if the request is ajax:

def index(request):
    if request.is_ajax() and request.method='POST':
        print(request.POST)
        # process post data

Django use X-Requested-With to detect an ajax request, take a look of How django detect ajax request the sendData function is originated from Mozilla Docs

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, but I tried that and I am still getting the same 403 forbidden error from the Django server. XHR.send(FD) had failed from the client-side. Any more ideas?
@rajasaid this works fine on my machine, also you can set request header before the request is sent using: XHR.setRequestHeader('X-CSRFToken', '{{ csrf_token}}') More info here docs.djangoproject.com/en/3.0/ref/csrf/#ajax
it worked after I added the get cookie function read from the Django docs, see my answer.
0

the following code made it happen:

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

function sendData(){
    const XHR = new XMLHttpRequest();
    // Set up our request
    var csrftoken = getCookie('csrftoken');
    XHR.open("POST", "/order_pizza" );
    XHR.setRequestHeader('X-Requested-With', 'XMLHttpRequest')
    XHR.setRequestHeader('X-CSRFToken', csrftoken)
    // Bind the FormData object and the form element
    let FD = new FormData();
    // append the token
    FD.append('csrfmiddlewaretoken', csrftoken);

    let username = localStorage.getItem('username');
    FD.append('username', username);

    // The data sent is what the user provided in the form
    XHR.send(FD);
}

obviously we had to retrieve the csrf cookie first before we could use it as a form data.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.