繁体   English   中英

Django:AJAX + CSRF POST产生403

[英]Django: AJAX + CSRF POST gives 403

我有一个简单的代码,其中包含CSRF令牌的Django对URL进行POST调用。 当我将javascript代码粘贴到<script>标记内的模板中时,它可以正常工作,但是,一旦我将代码移动到静态文件中,就会收到HTTP 403响应。 这很奇怪!

这是代码:

$(document).ready(function() {
    $(".like-button").click(function(event) {
        $.ajax({
            url: <relative path of URL>,
            type: "POST",
            data: {
                csrfmiddlewaretoken: "{{ csrf_token }}",
                // other data items
            },
            success: function(data, textStatus, jqXHR) {},
            error: function(jqXHR, textStatus, errorThrown) {}
        });
        // other javascript code to toggle like button class
    });
});

这是将静态文件包含在Django模板中的方法:

{% block javascript %}
{% load static %}
<script type="text/javascript" src="{% static 'app/app.js' %}"></script>
{% endblock %}

该文件位于静态目录中:

app
├── static
│   └── app
│       └── app.js

和静态设置为:

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

注意,我的设置中还没有STATICFILE_DIRS 由于console.log()语句工作得很好,因此我可以验证该文件正在加载和执行。 但是,我在POST收到HTTP 403请求。

当您直接使用标签时,django将处理模板,并用正确的令牌替换csrfmiddlewaretoken: "{{ csrf_token }}"

现在,当您使用静态文件时,该变量不会被替换。 为了添加令牌,您应该配置django文档描述的ajax调用: https : //docs.djangoproject.com/en/1.7/ref/contrib/csrf/#ajax

      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]);
            if (cookie.substring(0, name.length + 1) == (name + '=')) {
              cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
              break;
            }
          }
        }
        return cookieValue;
      }
      var csrftoken = getCookie('csrftoken');
      $.ajaxSetup({
        beforeSend: function(xhr, settings) {
          xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
      });

从Django文档中:

NOTE:
The CSRF token is also present in the DOM, but only if explicitly
included using csrf_token in a template. The cookie contains the
canonical token; the CsrfViewMiddleware will prefer the cookie to the
token in the DOM. Regardless, you’re guaranteed to have the cookie if
the token is present in the DOM, so you should use the cookie!

jQuery cookie插件:

var csrftoken = $.cookie('csrftoken');

https://docs.djangoproject.com/zh-CN/1.7/ref/contrib/csrf/

没有直接在模板上呈现的任何静态文件都不能使用django的模板引擎。 您需要使用csrf cookie。

在运行时检查您的JavaScript,您会注意到template变量是一个空字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM