【问题标题】:How to add Django's CSRF token to the header of a jQuery POST request?如何将 Django 的 CSRF 令牌添加到 jQuery POST 请求的标头?
【发布时间】: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 令牌的值。

【问题讨论】:

    标签: javascript jquery django django-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>
      

      【讨论】:

        猜你喜欢
        • 2019-12-22
        • 2015-04-09
        • 2016-09-19
        • 2017-11-29
        • 2019-12-20
        • 1970-01-01
        • 2013-12-16
        • 2020-02-04
        • 2019-11-30
        相关资源
        最近更新 更多