28👍
✅
Figured this out. The issue is that fetch
doesn’t include cookies by default.
Simple solution is to add credentials: "same-origin"
to the request and it works (with the form field but without the headers). Here’s the working code:
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'));
fetch("/upload/", {
method: 'POST',
body: data,
credentials: 'same-origin',
})
👤Cory
24👍
Your question is very close to success. Here is a json way if you do not want the form method. Btw, @Cory’s form method is very neat.
- Neat way with 3rd library
let data = {
'file': file,
'fileName': file.name,
};
// You have to download 3rd 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 cumbersome way, but without any 3rd 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 following function are copying 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();
// 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;
}
- [Django]-How to implement a "back" link on Django Templates?
- [Django]-Which CAS implementation to use in django?
- [Django]-How to add a new field to a model with new Django migrations?
5👍
There is a simple solution to this without any third party libraries.
In your templates scripts. Do this.
fetch("your_post_url",
{
method: "POST",
body: JSON.stringify(data),
headers: { "X-CSRFToken": '{{csrf_token}}' },
}
).then(res => {
//process your response
}
- [Django]-How do I run tests for all my Django apps only?
- [Django]-Adding new custom permissions in Django
- [Django]-Django Rest Framework: Access item detail by slug instead of ID
Source:stackexchange.com