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

7
我正在尝试制作一个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”行:

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令牌的值。

2个回答

4
你缺少单引号,请尝试像下面这样写。
$(".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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接