如何将Django的CSRF令牌添加到jQuery POST请求的标头中?

问题描述 投票:4回答:2

我正在尝试使用动态预填充字段制作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>

但是,当我选择一个下拉选项时,我会得到一个

新:17 Uncaught SyntaxError:意外的令牌 -

它来自X-CSRFToken: csrftoken线:

enter image description here

有人能指出我这个代码有什么问题吗? (我试过从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标记的值。

javascript jquery django django-csrf
2个回答
3
投票

您缺少单引号,请尝试以下操作。

$(".auto-submit").change(function() {
    $.post({
        url: "{% url 'get-checkin-type' %}",
        data: $(".auto-submit option:selected").val(),
        headers: {
            'X-CSRFToken': csrftoken
        }
    })
});

3
投票

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>
© www.soinside.com 2019 - 2024. All rights reserved.