没有表格的Django CSRF令牌

听起来很奇怪,但是使用Javascript(例如AJAX)发布内容而不使用表单的情况如何(可以从表面读取多个内容)。

我应该在哪里放置csrf_token模板标签? 我已经添加了AJAX修复程序: https : //docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax

…但我得到“CSRFvalidation失败。请求中止。” 404错误。

您必须在AJAX请求中设置自定义HTTP标头X-CSRFToken 。 请参阅: https : //docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax

如果你已经遵循了这个建议,它应该是有效的。 使用像Firebug这样的东西来监视正在发送的请求并检查标头以确保真正传递自定义标头。 如果不是,那么请再次检查您的实施,以确保您按照文档描述的那样执行。

另请注意:

由于jQuery 1.5中引入了一个错误,上面的示例将无法在该版本上正常运行。 确保你至少运行jQuery 1.5.1。

这段代码很简单:

 $.ajaxSetup({ data: {csrfmiddlewaretoken: '{{ csrf_token }}' },}); 

看到更多: https : //stackoverflow.com/a/7715325/1743582

每个会话分配一个CSRF令牌(即每次登录时)。 因此,在您希望获取用户输入的某些数据并将其作为ajax调用发送到受csrf_protect装饰器保护的某个函数之前,请尝试在从用户获取此数据之前查找正在调用的函数。 例如,必须呈现一些模板,用户在该模板上输入数据。 该模板由某个函数呈现。 在此函数中,您可以按如下方式获取csrf标记:csrf = request.COOKIES [‘csrftoken’]现在在上下文字典中传递此csrf值,以对照正在呈现的模板。 现在在该模板中写下这一行:现在在你的javascript函数中,在发出ajax请求之前,写下这个:var csrf = $(’#csrf’)。val()这将选择传递给模板的token的值并将其存储在变量中CSRF。 现在在进行ajax调用时,在你的post数据中,也传递这个值:“csrfmiddlewaretoken”:csrf

即使您没有实现django表单,这也会有效。

实际上,这里的逻辑是:您需要可以从请求获得的令牌。 因此,您只需要确定登录后立即调用的函数。一旦有了这个令牌,可以再进行一次ajax调用来获取它或将其传递给ajax可访问的某个模板。

如果您希望在没有表单的情况下发布,则配置CSRF令牌有两个步骤。 基本上从Cookie获取csrftoken ,并使用csrftoken设置Header(在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(在POST数据之前)。

 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'); } }); }