簡體   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