听起来很奇怪但是使用Javascript(例如AJAX)在不使用表单的情况下发布内容的场景(可以从表面读取多个内容)。
我应该在哪里放置csrf_token模板标签?我已经添加了AJAX修复: https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax
...但我得到“CSRF验证失败。请求中止。” 404错误。
答案 0 :(得分:13)
您必须在AJAX请求中设置自定义HTTP标头X-CSRFToken
。请参阅:https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax
如果您已经遵循了该建议,它应该正常工作。使用像Firebug这样的东西来监视正在发送的请求并检查标头以确保真正传递自定义标头。如果不是,那么请再次检查您的实施,以确保您按照文档描述的那样执行。
另请注意:
由于jQuery 1.5中引入了一个错误,上面的示例在该版本上无法正常运行。确保你至少运行jQuery 1.5.1。
答案 1 :(得分:1)
这段代码很简单:
$.ajaxSetup({ data: {csrfmiddlewaretoken: '{{ csrf_token }}' },});
答案 2 :(得分:0)
为每个会话分配一个CSRF令牌(即每次登录时)。因此,在您希望获取用户输入的某些数据并将其作为ajax调用发送到受csrf_protect装饰器保护的某个函数之前,请尝试在从用户获取此数据之前查找正在调用的函数。例如。必须呈现某些模板,用户在该模板上输入数据。该模板由某些函数呈现。在此函数中,您可以按如下方式获取csrf标记:csrf = request.COOKIES [' csrftoken']现在在上下文字典中传递此csrf值,以对照哪个模板进行渲染。现在在该模板中写下这一行:现在在你的javascript函数中,在发出ajax请求之前,写下这个:var csrf = $('#csrf')。val()这将选择传递给模板的令牌值并将其存储在变量csrf中。现在在进行ajax调用时,在你的帖子数据中,也传递这个值:" csrfmiddlewaretoken":csrf
即使您没有实现django表单,这也会有效。
事实上,这里的逻辑是:你需要你可以从请求获得的令牌。所以你只需要在登录后立即找出被调用的函数。一旦你有了这个令牌,要么再做一个ajax调用来获取它,或者把它传递给你的ajax可以访问的模板。
答案 3 :(得分:0)
如果您希望在没有表单的情况下发布,则配置CSRF令牌有两个步骤。基本上从Cookie获取csrftoken
,并使用csrftoken设置标头(在POST数据之前)。
1)从Cookie中获取csrftoken
。
// Function to GET csrftoken from Cookie
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// 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');
2)一旦你有csrftoken,你应该用csrftoken设置Header(在你发布数据之前)。
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
// Function to set Request Header with `CSRFTOKEN`
function setRequestHeader(){
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
}
function postSomeData() {
.....
setRequestHeader();
$.ajax({
dataType: 'json',
type: 'POST',
url: "/url-of-some-api/",
data: data,
success: function () {
alert('success');
},
error: function () {
alert('error');
}
});
}