I am trying to generate a csrf token in javascript and use that with a POST request using fetch. In my html, I have the following script tag under head to generate the csrf token:
<head>
<script type="text/javascript">
var user = '{{request.user}}'
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;
}
var csrftoken = getCookie('csrftoken');
console.log(csrftoken)
</script>
</head>
Then under body, I have the following script tag where I retrieve the csrftoken variable and pass it to the 'X-CSRFToken' header in fetch():
<body>
<script type="text/javascript">
console.log('Hello World')
console.log(csrftoken)
var updateButtons = document.getElementsByClassName('update-cart')
for(i = 0; i < updateButtons.length; i++){
updateButtons[i].addEventListener('click', function(){
var productId = this.dataset.product
var action = this.dataset.action
console.log('productId: ', productId, 'action: ', action)
console.log('user: ', user)
if(user === 'AnonymousUser'){
console.log('Not logged in.')
}else{
updateUserOrder(productId, action)
}
})
}
function updateUserOrder(productId, action){
console.log('User is authenticated. Sending data...')
console.log(csrftoken)
var url = '/update_item/'
fetch(url, {
method: 'POST',
headers: {
'Content-Type':'application/json',
'X-CSRFToken':csrftoken,
},
body: JSON.stringify({'productId': productId, 'action': action})
})
.then((response) => {
return response.json()
})
.then((data) => {
console.log('data: ', data)
})
}
</script>
</body>
The csrftoken variable is displayed by all the console.log() calls but I still get the following exceptions:
(index):169 POST http://127.0.0.1:8000/update_item/ 500 (Internal Server Error)
updateUserOrder
Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0
views.py,
def update_item(request):
data = json.loads(request.data)
product_id = data['productId']
action = data['action']
print('action: ', action)
print('product_id: ', product_id)
customer = request.user.customer
product = Product.objects.get(id=product_id)
order, created = Order.objects.get_or_create(customer=customer, complete=False)
orderitem, created = OrderItem.objects.get_or_create(order=order, product=product)
if action == 'add':
orderitem.quantity += 1
elif action == 'remove':
orderitem.quantity -= 1
orderitem.save()
if orderitem.quantity <= 0:
orderitem.delete()
return JsonResponse('Item was added.', safe=False)
I cannot seem to figure out whether it is a syntax error or if I am setting the 'X-CSRFToken' header wrong. Other similar answers did not help.
Solved. It was not an issue with my javascript or the csrftoken variable therein. Rather it was in my server code.
In views.py, I typed data = json.loads(request.data)
. But it should be data = json.loads(request.body)
.