【问题标题】:Jquery and Django CSRF TokenJquery 和 Django CSRF 令牌
【发布时间】:2012-01-26 17:57:18
【问题描述】:

我有 2 个 html 页面。

一个父页面和一个子页面。子页面包含一个提交按钮,该按钮在父页面上运行代码以提交 Ajax 消息。

我使用 $.load() 方法加载子页面,然后在单击按钮时运行 $.ajax .POST 方法。此 post 方法仅将 JSON 字符串传递给 Python 代码。

当我在除 IE 之外的任何浏览器上执行此操作时,它都可以正常工作。但是,当我在 IE 中运行此代码时。我收到有关 CSRF 令牌的 Python / Django 错误。

认为原因是因为子页面只是当前页面本身的刷新,服务器端代码正在运行。

有谁知道我应该如何让它发挥作用。

干杯,

【问题讨论】:

    标签: jquery python django csrf


    【解决方案1】:

    您没有通过 POST 传递 csrf 令牌。尝试做我在 data 中所做的事情。即获取 csrf 令牌(或您自己的方法)并将其传递到您的参数中。

    $.ajax({
        url : url,
        type: "POST",
        data : {csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value},
        dataType : "json",
        success: function( data ){
            // do something
        }
    });
    

    【讨论】:

    • 这种方法很好,但是如果您发出许多 ajax 请求,您可能会发现将 CSRF 令牌作为标头传递会更方便。如需更多信息,请参阅django docs
    • 我觉得data: {..., 'csrfmiddlewaretoken': '{{ csrf_token }}'}, ... 更直接。
    • 或在.html 模板中:<script> var django_csrf_token = '{{ csrf_token }}'; </script> 可从静态.js 使用。
    【解决方案2】:

    如果您要发送 POST 请求正文,则可能更容易将 csrf 令牌添加为请求标头。我发现这种方法更容易阅读,因为它不会用令牌混淆请求正文。大多数 AJAX 请求将按照 Django 文档的建议将 csrf 令牌作为标头发送。

    function startTest(testId) {
      var payload = JSON.stringify({
        test_id : testId
      });
      $.ajax({
        url: "/test-service/",
        method: "POST",
        headers: {'X-CSRFToken': '{{ csrf_token }}'},
        data: payload,
        dataType: "json"
      }).done(function(response) {
        console.log(response.id + " " + response.name);
      }).fail(function (error) {
          console.log(error);
      });
    }
    

    【讨论】:

      【解决方案3】:

      来自 CSRF 和 AJAX 上的 docs

      CSRF 令牌也存在于 DOM 中,但只有在模板中使用 csrf_token 明确包含。 cookie 包含规范令牌; CsrfViewMiddleware 将更喜欢 cookie 而不是 DOM 中的令牌。无论如何,如果令牌存在于 DOM 中,则保证您拥有 cookie,因此您应该使用 cookie!

      示例 (也来自文档)

      // using jQuery
      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');
      

      或者可以使用任何其他与 cookie 交互的方式。

      【讨论】:

        猜你喜欢
        • 2013-08-11
        • 2016-08-03
        • 1970-01-01
        • 2021-07-14
        • 2020-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-05
        相关资源
        最近更新 更多