我的ajax发布请求被django禁止使用403

时间:2019-03-01 16:49:58

标签: django

我正在尝试在this video之后使用django和jquery进行关键字搜索

但是当我每次尝试代码时,它都会返回禁止的403!

html页面:

<div class="search-input">
  <form>
    {% csrf_token %}
    <button>بحـث</button>
    <input
      type="text"
      name="q"
      id="search"
      placeholder="Est: Game of thrones, Vikings or Deadpool"
    />
  </form>
</div>
<div class="search-results"></div>

urls.py:

path('search/', views.search_titles, name='search')

views.py:

def search_titles(request):
    if request.method == 'POST':
        search_text = request.POST['search_text']
    else:
        search_text = ''

    search_results = Media.objects.filter(
        is_published=True, title__contains=search_text)[:5]

    context = {
        'search_results': search_results
    }

    return render(request, 'partials/_search_results.html', context)

jquery文件:

$("#search").on("keyup", function() {
    $.ajax({
      type: "POST",
      url: "/search/",
      data: {
        search_text: $("#search").val(),
        csrfmiddlewaretoken: $("input[name=csrfmiddlewaretoken]").val()
      },
      success: searchSuccess,
      dataType: "html"
    });
  });

  function searchSuccess(data, textStatus, jqXHR) {
    $("search-results").html(data);
  }
});

search_results.html(我什至不知道其原因)

{% if search_results.count > 0 %} {% for result in search_results %}
<li>
  <a href="#">{{ result.title }}</a>
</li>
{% endfor %} {% else %}
<li>Nothing to show</li>
{% endif %}

1 个答案:

答案 0 :(得分:1)

这很可能发生,因为您没有正确设置AJAX来传递CSRF令牌。 Django docs的主要部分介绍了如何进行设置。这是短篇小说。

首先,您需要获取令牌:

如果您设置中的CSRF_USE_SESSIONS和CSRF_COOKIE_HTTPONLY为False,这是解决方法:

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

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

或,如果您设置中的CSRF_USE_SESSIONS或CSRF_COOKIE_HTTPONLY为True,请执行以下操作:

{% csrf_token %}
<script type="text/javascript">
// using jQuery
var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();
</script>

在两种情况下,您还都需要在AJAX请求上设置令牌:

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);
        }
    }
});