#javascript #django #csrf #django-csrf #csrf-token
#javascript #django #csrf #django-csrf #csrf-token
Вопрос:
Я пытаюсь сгенерировать токен csrf в javascript и использовать его с запросом POST с использованием выборки. В моем html у меня есть следующий тег script под заголовком для генерации токена csrf:
<head>
<script type="text/javascript">
var user = '{{request.user}}'
function getCookie(name) {
let cookieValue = null;
if (document.cookie amp;amp; 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>
Затем в разделе body у меня есть следующий тег скрипта, где я извлекаю переменную csrftoken и передаю ее в заголовок ‘X-CSRFToken’ в 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>
Переменная csrftoken отображается всеми вызовами console.log(), но я все равно получаю следующие исключения:
(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)
Кажется, я не могу понять, является ли это синтаксической ошибкой или я неправильно устанавливаю заголовок ‘X-CSRFToken’. Другие подобные ответы не помогли.
Комментарии:
1. Вы должны проверить, как ваш сервер обработал запрос, и в итоге выдал ошибку.
<
скорее всего, в JSON, потому что сервер ответил страницей с ошибкой.2. @Teemu На сервере, я возвращаю ответ Json. Я обновил свой вопрос с помощью функции просмотра, чтобы вы могли проверить. Но запрос POST вызывает сбой проверки csrf, поэтому я получаю эту ошибку.
3. Нет, вы намереваетесь вернуть JSON, но серверный код завершается ошибкой ( внутренняя ошибка сервера 500 ), и он отвечает либо страницей ошибки, либо сообщением об ошибке, содержащим это
<
. Нажмите F12, откройте вкладку Networktab и сделайте что-нибудь на странице, чтобы был вызван запрос. Когда сервер отвечает, ответ можно увидеть в списке на вкладке Сеть. Щелкните ответ и проверьте, что на самом деле есть в теле ответа. Затем перейдите к журналам сервера, чтобы узнать, что пошло не так.4. Правильно. Ошибка была в моем коде на стороне сервера. В views.py , Я напечатал
data = json.loads(request.data)
. Но это должно бытьdata = json.loads(request.body)
.
Ответ №1:
Решаемая. Это не было проблемой с моим javascript или переменной csrftoken в нем. Скорее это было в моем серверном коде. В views.py , Я напечатал data = json.loads(request.data)
. Но это должно быть data = json.loads(request.body)
.