0

I'm trying to make a ajax post request to django this is js snippet

const xhr = new XMLHttpRequest();

            console.log(xhr.readyState);
            
            xhr.open('POST', '');

            var data = '{% csrf_token %}';

            console.log(data);

            console.log(typeof(data));

            xhr.setRequestHeader('X-CSRF-Token', data);
            
            xhr.onload = function(){

                console.log(xhr.readyState);

                console.log(xhr.status);

                if(xhr.status == 200){
                
                    console.log(JSON.parse(xhr.responseText));
                
                }else{
                    console.log("Something went wrong!!");
                }

            }
            
            xhr.send({'userId' : userId})
        }

This is my error log: enter image description here

I've been getting a 403 forbidden error can anybody help me out?

juliomalves
  • 42,130
  • 20
  • 150
  • 146
  • It's saying the CSRF token is missing or incorrect - but it's apparent from your code that you've tried to include it. It's not instantly obvious to me what's wrong, but I have to ask first - what do you see for the `console.log(data)`? – Robin Zigmond Mar 07 '21 at 01:01
  • Does this answer your question? [Django CSRF check failing with an Ajax POST request](https://stackoverflow.com/questions/5100539/django-csrf-check-failing-with-an-ajax-post-request) – Ivan Starostin Mar 07 '21 at 09:10
  • 1
    @RobinZigmond console.log(data) is printing out a input tag of type hidden – sashi dhar Mar 08 '21 at 01:56
  • 1
    Oh of course, thanks - it's been a while since I used Django and forgot the `csrf_token` that goes in the template is the hidden input that submits the token, not the token itself. Looks like you've got your answer though (don't forget to accept and/or upvote it, if it helped). – Robin Zigmond Mar 08 '21 at 08:40

2 Answers2

1

This function should get you the csrf-token

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

then:

const csrftoken = getCookie('csrftoken');

to get the csrf-token.

What also might be worth looking at is changing X-CSRF-Token

xhr.setRequestHeader('X-CSRF-Token', data);

to X-CSRFToken

xhr.setRequestHeader('X-CSRFToken', data);

hope this helps

ThomasVR
  • 11
  • 4
0

The {% csrf_token %} in the templates page translates to:

<input type="hidden" name="csrfmiddlewaretoken" value="WRWu3DwbdHDl1keRwSqUNrvcwZXqhCzkInEGVftyuwWG0v5kBBzeGrZ34wKpjFB5">

We need to get the CSRF token , i.e., the value of this element:

x = document.getElementsByName("csrfmiddlewaretoken")[0].value; 

Then, we need to pass this value to the setRequestHeader method of the JSON request, with "X-CSRFToken" as the first argument:

function requestJSON() {
         x = document.getElementsByName("csrfmiddlewaretoken")[0].value;
        jsonRequest = new XMLHttpRequest();
        jsonRequest.overrideMimeType("application/json");
        jsonRequest.onreadystatechange = function() {
         if (this.readyState == 4 && this.status == 200 ) {
             var j = JSON.parse(this.responseText); 
             // do whatever with the JSON data
             } 
         else {console.log(this.status);}
         };
        jsonRequest.open("POST","url/");
        jsonRequest.setRequestHeader("content-type","application/x-www-form-urlencoded");
        jsonRequest.setRequestHeader("X-CSRFToken",x);
        jsonRequest.send();
}