Utilizing correct Django CSRF validation when making a fetch post request

I've been experimenting with JavaScript's fetch library to perform a form submission on my Django application. Despite my efforts, I keep running into CSRF validation issues.

The Ajax documentation suggests specifying a header, which I have attempted to implement.

I've also tried fetching the token using a templatetag and including it in the form data.

Unfortunately, neither method seems to resolve the problem.

Below is the sample code that includes both the form value and the header:

let data = new FormData();
data.append('file', file);
data.append('fileName', file.name);
// add form input from hidden input elsewhere on the page
data.append('csrfmiddlewaretoken', $('#csrf-helper input[name="csrfmiddlewaretoken"]').attr('value'));
let headers = new Headers();
// add header from cookie
const csrftoken = Cookies.get('csrftoken');
headers.append('X-CSRFToken', csrftoken);
fetch("/upload/", {
    method: 'POST',
    body: data,
    headers: headers,
})

While I have successfully achieved this using jQuery, I wanted to explore the possibility of utilizing fetch.

Answer №1

Figured it out. The main issue here is that fetch does not automatically send cookies.

The solution is fairly simple - just add credentials: "same-origin" to your request and it should work fine (especially with the form data, albeit without the headers). Here is the revised and working code:

let formData = new FormData();
formData.append('file', file);;
formData.append('fileName', file.name);
// include form input from a hidden field elsewhere in the document
formData.append('csrfmiddlewaretoken', $('#csrf-helper input[name="csrfmiddlewaretoken"]').attr('value'));
fetch("/upload/", {
    method: 'POST',
    body: formData,
    credentials: 'same-origin',
})

Answer №2

Your inquiry is on the brink of triumph. Below is a way to handle it in a JSON format if you prefer not to use the form method. Also, kudos to @Cory for their smart form method.

  1. Efficient method with a 3rd party library
let data = {
    'file': file,
    'fileName': file.name,
};
// To implement this, you'll need to download the 3rd party Cookies library
// https://docs.djangoproject.com/en/dev/ref/csrf/#ajax
let csrftoken = Cookies.get('csrftoken');
let response = fetch("/upload/", {
    method: 'POST',
    body: JSON.stringify(data),
    headers: { "X-CSRFToken": csrftoken },
})

2. Another approach that may seem complex, but doesn't require a 3rd party library

let data = {
    'file': file,
    'fileName': file.name,
};
let csrftoken = getCookie('csrftoken');
let response = fetch("/upload/", {
    method: 'POST',
    body: JSON.stringify(data),
    headers: { "X-CSRFToken": csrftoken },
})

// The below function is taken from 
// https://docs.djangoproject.com/en/dev/ref/csrf/#ajax
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();
            // Checking if this cookie string starts with the desired name
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

Answer №3

If you're looking for a straightforward fix to this issue and don't want to rely on any external libraries, here's a solution you can implement directly in your template scripts.

fetch("your_post_url",
        {
            method: "POST",
            body: JSON.stringify(data),
            headers: { "X-CSRFToken": '{{csrf_token}}' },
        }
    ).then(res => {
        //process your response
    }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ways to swap out an img element with an almost identical gif element while maintaining its precise placement consistently

I am facing an issue in my code where a random element is generated within the body and when clicked, it is replaced with another gif element. I am using offset() to obtain the top and left values of the original image, and then using replaceWith() to swap ...

What is the best way to retrieve nested reference data all at once from a Firestore document?

I have two distinct collections stored within my Firestore database. The first collection is users, and it can be visualized as shown here: https://i.stack.imgur.com/AKlyM.png The second collection is posts, represented by the following structure: http ...

Tips for organizing appended <li> elements using jQuery

Being a novice in the realm of programming, I ask for your understanding as I pose what may seem like a simple question. Up until now, I have been unable to find a satisfactory solution to my issue. Within my HTML Code lies an unordered list, serving sole ...

Is Firebug a necessary tool for the functioning of my website?

I'm currently tackling a new project that involves complex javascript development. Unfortunately, I am unable to share any code specifics at this time. Initially, my script functioned correctly in Firefox 3.0 but encountered issues when tested on Fir ...

Encountering NaN values in JavaScript arrays

I'm facing an issue with my HTML code that is supposed to make ball(s) bounce around the canvas. However, when I set the arrays storing the coordinates to random positions and test with alert("Co-ordinates " + (cirX[i]) + " x " + (cirY[i]));, it retur ...

Hide modal once form has been successfully submitted

Is it best practice to pass handleClose into ForgotPasswordFormComponent in order to close the modal after form submission, or is there a better way to achieve this? <StyledModal open={openModal} onClose={handleClose} closeAfterTransition slots={{ bac ...

Displaying an array of objects in the MUI Datagrid interface

I have integrated Redux into my project to retrieve data from the API, and this is a snapshot of the data structure: https://i.stack.imgur.com/jMjUF.png My current challenge lies in finding an effective way to display the information stored within the &a ...

Is it possible to programmatically alter the resource class in Django Import-Export admin depending on the user group?

Utilizing the Django Import-Export library to streamline export functionalities in my Django admin interface has been quite helpful. I'm faced with a specific need where I have to dynamically adapt the resource class depending on the user's group ...

Exploring the use of leaflets within LitElement

I have been working on a project involving LitElement components and I am looking to incorporate Leaflet into it. However, I am encountering difficulties with displaying the map properly. After installing Leaflet through npm in my project, I created a clas ...

What is the best way to retrieve the value of a checkbox element in React.js when submitting a form?

Whenever I try to submit a form, I encounter an issue where I am unable to retrieve the value of the checked boxes (I don't mean the check value but the actual value attribute of the HTML element). Here is an example of my element in the parent compo ...

Combining two arrays by finding common elements

Currently, I am working on a project where I retrieve data from the server, and each piece of data has to adhere to a specific format: const DATA = [ { title: {title: 'Main dishes'}, data: [ {_id: 1, type: 'Pizza'}, ...

`Incorporate concurrent network requests in React for improved performance`

I am looking to fetch time-series data from a rest service, and currently my implementation looks like this async function getTimeSeriesQuery(i) { // Demonstrating the usage of gql appollo.query(getChunkQueryOptions(i)) } var promises = [] for(var i ...

Determining the pageY value of a div element with overflow-y styling

Currently, I have implemented a script that tracks the mouse's position upon hover. My goal is to integrate this script within a div that has overflow-y: scroll The script currently utilizes pageY which identifies the position relative to the windo ...

How can I extract the id of a clicked item and pass it to a different page with Jquery?

Facing an issue where the attribute value of a clicked href tag is not retained after browser redirection. Initially, when clicking on the href tag, the value is displayed correctly. However, upon being redirected to the peoplegallery_album, the id becomes ...

What makes this CSS causing render blocking?

I've been meticulously following the Google PageSpeed guidelines in order to optimize the performance of my website. Upon running an analysis, Google provides me with a score based on their set guidelines. There's one particular guideline that ...

Typescript inheritance results in an undefined value being returned

I am trying to understand the code below, as I am confused about its functionality. In languages like C# or Java, using the base or super keyword usually returns values, whereas in TypeScript, I am receiving "undefined". However, when I switch from using " ...

Searching for a method to retrieve information from an API using jQuery in Node.js?

I'm currently working on fetching data from an api to display on the front-end. This is my server-side code - app.get('/chats',function(req,res){ User.find({}).exec(function(err,user){ res.send(user); }); }); On the clie ...

Error: Uncaught Type Error - Attempted to access property 'then' of an undefined variable. This issue occurred when attempting to use a

I attempted to use the code below, considering that node operates asynchronously and in order to execute my code sequentially I added a then function. However, I encountered the error TypeError: Cannot read property 'then' of undefined. The code ...

Is it possible to incorporate URLs in Django views?

My current content is 'Please get me the Python book you talked about, @friend' Now, in my views.py: new_content = re.sub(r'(@\w+)', r"<a href='#'>\g<0></a>>", content) After applying this, I ...

Can all browser console messages and errors be sent to a different machine using a pipeline?

Currently, I am in the process of troubleshooting a javascript error that is occurring within a Cordova app's InAppBrowser on an Android device. Despite being able to connect to the web-view on the phone using Chrome's remote debugging tools, the ...