如何在 AJAX 中传递 Django csrf 令牌(没有 jQuery)
Posted
技术标签:
【中文标题】如何在 AJAX 中传递 Django csrf 令牌(没有 jQuery)【英文标题】:How to pass Django csrf token in AJAX (without jQuery) 【发布时间】:2016-08-19 01:15:23 【问题描述】:基于w3schools ajax example,我正在尝试进行删除调用,然后从表中删除相应的行。这里有很多关于如何使用 JQuery 的答案,但我没有这样做。我找到了this answer,它让我这样写我的 javascript:
function deleteFullLicense(rowid, objectid)
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function()
if (xhttp.readyState == 4 && xhttp.status == 204)
row = document.getElementById(rowid);
row.parentNode.removeChild(row);
else
window.alert("Something went wrong. The delete failed.");
;
xhttp.open("POST", "deleteLicense/" + objectid, true);
xhttp.send('csrfmiddlewaretoken': ' csrf_token ');
但我收到了Forbidden (CSRF token missing or incorrect.)
消息。我应该如何发送令牌?
【问题讨论】:
你需要将is设置为header。也许这可以帮助你:***.com/questions/22063612/… 我尝试将其设置为标题使用:xhttp.setRequestHeader("csrfmiddlewaretoken", ' csrf_token ')
但这没有区别。还有什么需要做的吗?
【参考方案1】:
事实证明,如果我将其命名为 X-CSRFToken
,它就会起作用。发现了它here if you want to read more。
function deleteFullLicense(rowid, objectid)
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function()
if (xhttp.readyState == 4 && xhttp.status == 204)
row = document.getElementById(rowid);
row.parentNode.removeChild(row);
;
xhttp.open("POST", "deleteLicense/" + objectid, true);
xhttp.setRequestHeader("X-CSRFToken", ' csrf_token ')
xhttp.send();
【讨论】:
【参考方案2】:标头名称X-CSRFToken
实际上来自Django settings.py
中的参数CSRF_HEADER_NAME。当接收到前端请求(例如 ajax 调用)时,Django 内部会检查头参数并将X-CSRFToken
转换为HTTP_X_CSRFTOKEN
,这是CSRF_HEADER_NAME
的默认值。
更好的方法是:
转换CSRF_HEADER_NAME
的值
将上一步转换后的值渲染到 html 模板中
在前端代码(例如 HTML 模板或单独的 js 文件)中,使用该值和 CSRF 令牌在每个 ajax 调用上创建自定义标头以提交表单。
这是一个简单的例子:
在settings.py
CSRF_HEADER_NAME = "HTTP_ANTI_CSRF_TOKEN"
在views.py
的视图函数中
from django.conf import settings
from django.http.request import HttpHeaders
prefix = HttpHeaders.HTTP_PREFIX
converted = settings.CSRF_HEADER_NAME[len(prefix):]
converted = converted.replace('_','-')
# so the value HTTP_ANTI_CSRF_TOKEN is converted to ANTI-CSRF-TOKEN,
return Response(context='custom_csrf_header_name':converted)
在您的 HTML 模板中(不是好习惯,因为这只是简单的示例)
<script>
// Note that the value is 'ANTI-CSRF-TOKEN'. when this header name goes to
// backend server, Django will internally convert it back to 'HTTP_ANTI_CSRF_TOKEN'
var custom_csrf_header_name = " custom_csrf_header_name ";
// the ajax part is almost the same as described in the accepted answer
...
xhttp.setRequestHeader(custom_csrf_header_name, ' csrf_token ')
...
</script>
【讨论】:
以上是关于如何在 AJAX 中传递 Django csrf 令牌(没有 jQuery)的主要内容,如果未能解决你的问题,请参考以下文章
如何将 POST 数据中的 CSRF 令牌传递给 Django?