403 Запрещенная ошибка при создании запроса ajax Post в структуре Django

Я пытаюсь интегрировать jquery в веб-приложение, которое я создаю с помощью рамки Django. Тем не менее, я с трудом пытаюсь сделать простой вызов ajax для работы. Мой файл шаблона, который содержит форму html и javascript для обработки вызова ajax, выглядит следующим образом:

<script type="text/javascript">
$(document).ready(function() {
$( "#target" ).submit(function() {
console.log('Form was submitted');
$.ajax({
        type: "POST",
        url: "/hello/",  // or just url: "/my-url/path/"
        data: {
            query: $( "#query" ).val()   
        },
        success: function(data) {
            console.log(data);
        }
    });
return false;
  });   
  })
</script>
<form id="target" action="." method="post">{% csrf_token %}
 <input id= "query" type="text" value="Hello there">
 <input type="submit" value="Search Recent Tweets">
</form>

Мой views.py, который должен обрабатывать вызов ajax, выглядит следующим образом:

 from django.core.context_processors import csrf
 from django.shortcuts import render_to_response
 from django.template.loader import get_template
 from django.template import Context,RequestContext
 from django.views.decorators.csrf import ensure_csrf_cookie
 from django.http import HttpResponse

 # access resource
 def hello(request):
  c = {}
  c.update(csrf(request))
  if request.is_ajax():
        t = get_template('template.html')
        #html = t.render(Context({'result': 'hello world'}))
        con = RequestContext(request, {'result': 'hello world'})
        return render_to_response('template.html', c, con)
  else:
        return HttpResponse('Not working!') 

Я попытался выполнить официальную документацию по Защита от перекрестного запроса запросов и также рассмотрел несколько вопросов stackoverflow, направленных на аналогичную проблему. Я включил {% csrf_token %} в файл шаблона html, но он все еще не работает. Я получаю сообщение об ошибке в консоли, предполагая, что вызов ajax не удалось:

POST http://127.0.0.1:8000/hello/ 403 (FORBIDDEN)   

Как передать переменную result вместе с моим HTTP-ответом и получить вызов ajax для бесперебойной работы? Любая помощь глубоко ценится.

Edit-1

Я не предположительно передавал токен csrf вместе с моим почтовым запросом. В соответствии с документацией я добавил следующий код в свой шаблон javascript:

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');
console.log(csrftoken);

//Ajax call
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
    crossDomain: false, // obviates need for sameOrigin test
    beforeSend: function(xhr, settings) {
        if (!csrfSafeMethod(settings.type)) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});

Когда я обновляю страницу шаблона html в браузере, я получаю null в консоли, предполагая, что cookie не установлен или не определен. Что мне не хватает?

Ответ 1

Потому что вы не опубликовали csrfmiddlewaretoken, поэтому Django запрещает вам. этот документ может вам помочь.

Ответ 2

Для ленивых парней:

Первый файл cookie для загрузки: http://plugins.jquery.com/cookie/

Добавьте его в свой html:

<script src="{% static 'designer/js/jquery.cookie.js' %}"></script>

Теперь вы можете создать рабочий запрос POST:

var csrftoken = $.cookie('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);
        }
    }
});

$.ajax(save_url, {
    type : 'POST',
    contentType : 'application/json',
    data : JSON.stringify(canvas),
    success: function () {
        alert("Saved!");
    }

})

Ответ 3

Я нахожу все предыдущие ответы на месте, но вставляю вещи в контекст.

Запрещенный ответ 403 поступает из промежуточного программного обеспечения CSRF (см. Защита от перекрестных запросов на использование сайтов):

По умолчанию "403 Запрещенный ответ" отправляется пользователю, если входящий запрос не выполняет проверки, выполняемые CsrfViewMiddleware.

Доступны многие варианты. Я бы рекомендовал следовать ответу @fivef, чтобы jQuery добавлял заголовок X-CSRFToken перед каждым запросом AJAX с $.ajaxSetup.

Этот ответ требует плагина jQuery для cookie. Если это нежелательно, другая возможность заключается в добавлении:

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_COOKIE_HTTPONLY установлено значение True, которое часто происходит как Защитное промежуточное программное обеспечение рекомендует, поэтому cookie не существует, даже если используется @ensure_csrf_cookie(). В этом случае {% csrf_token %} должен быть представлен в каждом виде, который производит вывод, например <input name="csrfmiddlewaretoken" value="cr6O9...FUXf6" type="hidden">. Таким образом, переменная csrfToken была бы просто получена:

var csrftoken = $('input[name="csrfmiddlewaretoken"]').val();

Конечно, потребуется $.ajaxSetup.

Другие доступные опции, но не рекомендуется, должны отключить промежуточное программное обеспечение или защиту csrf для конкретной формы с помощью @csrf_exempt().

Ответ 4

Самое быстрое решение, если вы не встраиваете js в шаблон:

Put <script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script> <script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script> перед ссылкой на файл script.js в шаблоне, затем добавьте csrfmiddlewaretoken в словарь data:

$.ajax({
            type: 'POST',
            url: somepathname + "do_it/",
            data: {csrfmiddlewaretoken: window.CSRF_TOKEN},
            success: function() {
                console.log("Success!");
            }
        })

Если вы встраиваете свои js в шаблон, это просто: data: {csrfmiddlewaretoken: '{{ csrf_token }}'}

Ответ 5

Чтобы установить файл cookie, используйте ensure_csrf_cookie decorator в вашем представлении:

from django.views.decorators.csrf import ensure_csrf_cookie

@ensure_csrf_cookie
def hello(request):
    code_here()

Ответ 6

Убедитесь, что вы не кэшируете страницу/представление, в котором отображается ваша форма. Это может быть кеширование вашего CSRF_TOKEN. Случилось со мной!

Ответ 7

Попробуйте включить этот декоратор в свой код отправки

from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt     
@method_decorator(csrf_exempt, name='dispatch')
def dispatch(self, request, *args, **kwargs):
     return super(LessonUploadWorkView,self).dispatch(request,*args,**kwargs)

Ответ 8

С SSL/https и с CSRF_COOKIE_HTTPONLY = False у меня все еще нет csrftoken в cookie, либо используя функцию getCookie (name), предложенную в django Doc или jquery.cookie.js, предложенный пятьf.

Резюме Wtower идеально подходит, и я думал, что он будет работать после удаления CSRF_COOKIE_HTTPONLY с settings.py, но он не работает в https!

Почему csrftoken не отображается в документе document.cookie???

Вместо того, чтобы получать

"django_language = fr; csrftoken = rDrGI5cp98MnooPIsygWIF76vuYTkDIt"

Я получаю только

"django_language = Fr"

Почему? Как SSL/https удаляет X-CSRFToken из заголовков Я думал, что это связано с параметрами прокси-сервера Nginx, но, по-видимому, не... Любая идея?

В отличие от django doc Notes, кажется невозможным работать с csrf_token в файлах cookie с https. Единственный способ передать csrftoken через DOM с помощью {% csrf_token%} в html и получить его в jQuery с помощью

var csrftoken = $('input[name="csrfmiddlewaretoken"]').val();

Затем можно передать его в ajax либо заголовком (xhr.setRequestHeader), либо params.

Ответ 9

Вы видите "403 (ЗАПРЕЩЕНО)", потому что вы не отправляете параметр "csrfmiddlewaretoken". В шаблоне каждая форма имеет следующее: {% csrf_token%}. Вы должны добавить это: "csrfmiddlewaretoken": "{{csrf_token}}" к вашим данным ajax.

$(function(){
    $('.card-body').on('click',function(){
        $.ajax({
          type: "post",
          url: "{% url 'basket:remove'%}",
          data: {"product_code": "07316", "csrfmiddlewaretoken" : "{{csrf_token}}" }
        });
    })
});

Ответ 10

Вы должны изменить папку chmod 755 и файл (.php,.html) chmod 644.