【发布时间】:2021-03-10 21:34:14
【问题描述】:
我正在尝试在 javascript 中生成一个 csrf 令牌,并将其与使用 fetch 的 POST 请求一起使用。 在我的 html 中,我在 head 下有以下脚本标记来生成 csrf 令牌:
<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>
然后在 body 下,我有以下脚本标记,我在其中检索 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' 标头设置错误。其他类似的答案没有帮助。
【问题讨论】:
-
您必须检查您的服务器是如何处理请求的,并最终导致错误。
<很可能在 JSON 中,因为服务器已响应错误页面。 -
@Teemu 在服务器上,我正在返回 Json 响应。我已经用我的视图功能更新了我的问题,所以你可以检查一下。但是 POST 请求导致 csrf 验证失败,所以我收到了这个错误。
-
不,您打算返回 JSON,但服务器端代码失败(500 内部服务器错误),它响应错误页面或错误包含
<的消息。按 F12,打开 Network 选项卡并在页面上执行一些操作,以便调用请求。当服务器响应时,可以在“网络”选项卡的列表中看到响应。单击响应,然后检查响应正文中的实际内容。然后去服务器日志看看哪里出了问题。 -
正确。错误出现在我的服务器端代码中。在views.py 中,我输入了
data = json.loads(request.data)。但应该是data = json.loads(request.body)。
标签: javascript django csrf django-csrf csrf-token