基于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.)
消息。我该如何发送令牌?
答案 0 :(得分: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();
}
答案 1 :(得分:1)
标头名称X-CSRFToken
实际上来自Django settings.py
中的参数CSRF_HEADER_NAME。当收到前端请求(例如ajax调用)时,Django内部检查标头参数并将X-CSRFToken
转换为HTTP_X_CSRFTOKEN
的默认值CSRF_HEADER_NAME
。
更好的方法是:
CSRF_HEADER_NAME
的值这是一个简单的示例:
在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>