如何将 Django 的 CSRF 令牌添加到 jQuery POST 请求的标头?
Posted
技术标签:
【中文标题】如何将 Django 的 CSRF 令牌添加到 jQuery POST 请求的标头?【英文标题】:How to add Django's CSRF token to the header of a jQuery POST request? 【发布时间】:2018-08-09 03:55:16 【问题描述】:我正在尝试制作一个带有动态预填充字段的 Django 表单:也就是说,当从下拉菜单中选择一个字段 (checkin_type
) 时,其他字段会自动预填充相应的数据。为此,我想在选择下拉选项后立即向服务器发送 POST 请求。
到目前为止,我已经尝试了以下模板(遵循https://docs.djangoproject.com/en/2.0/ref/csrf/):
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js"></script>
<script>
$(document).ready(function()
var csrftoken = Cookies.get('csrftoken');
$(".auto-submit").change(function()
$.post(
url: "% url 'get-checkin-type' %",
data: $(".auto-submit option:selected").val(),
headers:
X-CSRFToken: csrftoken
)
);
);
</script>
<form action="" method="post">% csrf_token %
% for field in form %
<div class="% if field.name == 'checkin_type' %auto-submit% endif %">
field.errors
field.label_tag
field
</div>
% endfor %
<input type="submit" value="Send message" />
</form>
但是,当我选择一个下拉选项时,我会得到一个
new:17 Uncaught SyntaxError: Unexpected token -
来自X-CSRFToken: csrftoken
行:
有人可以指出这段代码有什么问题吗? (我尝试从https://developer.mozilla.org/en-US/docs/Web/javascript/Reference/Errors/Unexpected_token 查找它,但目前无法弄清楚)。
顺便说一句,从jQuery add CSRF token to all $.post() requests' data 看来,人们也可以将 CSRF 令牌添加到 POST 请求的data
,但这对我来说似乎不是最优雅的方法,文档指出
因此,有一种替代方法:在每个 XMLHttpRequest 上,将自定义 X-CSRFToken 标头设置为 CSRF 令牌的值。
【问题讨论】:
【参考方案1】:您缺少单引号,请尝试以下操作。
$(".auto-submit").change(function()
$.post(
url: "% url 'get-checkin-type' %",
data: $(".auto-submit option:selected").val(),
headers:
'X-CSRFToken': csrftoken
)
);
【讨论】:
【参考方案2】:PSK 的解决方案有效,但为了完整起见,这里是 Django 文档在进一步阅读(来自https://docs.djangoproject.com/en/2.0/ref/csrf/#setting-the-token-on-the-ajax-request)后概述的方法,它使用.ajaxSetup
覆盖所有请求一次对所有人来说:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/js-cookie@2/src/js.cookie.min.js"></script>
<script>
$(document).ready(function()
var csrftoken = Cookies.get('csrftoken');
function csrfSafeMethod(method)
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
$.ajaxSetup(
beforeSend: function(xhr, settings)
if (!csrfSafeMethod(settings.type) && !this.crossDomain)
xhr.setRequestHeader("X-CSRFToken", csrftoken);
);
$(".auto-submit").change(function()
$.post(
url: "% url 'get-checkin-type' %",
data: $(".auto-submit option:selected").val(),
)
);
);
</script>
【讨论】:
以上是关于如何将 Django 的 CSRF 令牌添加到 jQuery POST 请求的标头?的主要内容,如果未能解决你的问题,请参考以下文章
你如何在 django rest 框架中实现 CSRF 令牌?
如何将 POST 数据中的 CSRF 令牌传递给 Django?
使用 CSRF_COOKIE_HTTPONLY 将 Django CSRF 令牌传递给 Angular