Ошибка http 403 с django и ajax - PullRequest
2 голосов
/ 19 июля 2011

Я пробираюсь через 'Разработка веб-сайтов Django 1.0' и столкнулся с проблемой при использовании форм. Сервер пожаловался на что-то, касающееся csrf. Я мог бы решить это, добавив {% csrf_token %} сразу после тега формы. Я уже прочитал документацию на djangoproject.com, но должен признать, что не до конца понимаю, что именно здесь происходит. Я не использую промежуточные классы.

Настоящая проблема началась, когда я добрался до ajax. Я следовал инструкциям в книге к письму, но сервер начал жаловаться:

"POST /save/?ajax HTTP/1.1" 403 2332

Вот код, который может вызвать проблемы:

function bookmark_save() {
var item = $(this).parent();
var data = {
    url: item.find("#id_url").val(),
    title: item.find("#id_title").val(),
    tags: item.find("#id_tags").val()
};
$.post("/save/?ajax", data, function (result) {
    if (result != "failure") {
        item.before($("li", result).get(0));
        item.remove();
        $("ul.bookmarks .edit").click(bookmark_edit);
    }
    else {
        alert("Failed to validate bookmark before saving.");
    }
});
return false;

}

'/ save / & ajax' обрабатывается

if ajax:
    return render_to_response('bookmark_save_form.html', variables)

Здесь bookmark_save_form.html:

<form id="save-form" method="post" action="/save/">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="save" />
</form>

Насколько я понимаю, я должен передать csrf_token с запросом POST. Но я понятия не имею, как.

Любой совет по этому поводу был бы великолепен.

Ответы [ 5 ]

1 голос
/ 19 мая 2012

В настоящее время я тоже работаю над этой книгой и столкнулся с точно такой же проблемой, кстати. Не в первый раз! По сути, происходит то, что токен csrf не передается через запрос Ajax. Итак, короткий и простой ответ заключается в том, что вам нужно включить токен csrf - это ваш вызов ajax. Это достигается с помощью этого блока кода: https://docs.djangoproject.com/en/1.3/ref/contrib/csrf/#ajax

jQuery(document).ajaxSend(function(event, xhr, settings) {
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;
}
function sameOrigin(url) {
    // url could be relative or scheme relative or absolute
    var host = document.location.host; // host + port
    var protocol = document.location.protocol;
    var sr_origin = '//' + host;
    var origin = protocol + sr_origin;
    // Allow absolute or scheme relative URLs to same origin
    return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
        (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
        // or any other URL that isn't scheme relative or absolute i.e relative.
        !(/^(\/\/|http:|https:).*/.test(url));
}
function safeMethod(method) {
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
    xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
});

Затем я включил это как файл .js в мой user_page.html. После этого я мог безнаказанно звонить по Ajax!

0 голосов
/ 07 августа 2015

из django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def my_view(request):
...
0 голосов
/ 22 февраля 2013

Я работаю над книгой и просто столкнулся с той же проблемой. Вот простейшее решение, которое имеет преимущество, заключающееся в том, что Django не отключает защиту от csrf или не включает в себя декораторы или скрипты с такими утилитами, как 'sure_csrf_cookie'. Он просто передает токен:

В файле .js, который вы создали для хранения пользовательских сценариев jquery, добавьте следующую пару в переменную data в вашей функции bookmark_save ():

csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].val()

Таким образом, результирующая функция bookmark_save выглядит следующим образом:

function bookmark_save() {
    var item = $(this).parent();
    var data = {
        url: item.find("#id_url").val(),
        title: item.find("#id_title").val(),
        tags: item.find("#id_tags").val(),
        csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].val()
    };
    $.post("/save/?ajax", data, function (result) {
        if (result != "failure") {
            item.before($("li", result).get(0));
            item.remove();
            $("ul.bookmarks .edit").click(bookmark_edit);
        }
        else {
            alert("Failed to validate bookmark before saving.");
        }
    });
    return false;
}
0 голосов
/ 27 сентября 2011

Создайте файл Javascript.Я не знаю, как форматировать код - извините.Затем загрузите его после Jquery.

Это описано здесь

0 голосов
/ 19 июля 2011

Я вытащил это из проекта уже сделано. Это шаблон контактной формы. Имейте в виду, это для Джанго. Также, пожалуйста, обратитесь к книге Джанго http://www.djangobook.com/en/2.0/. На все мои вопросы ответила эта книга. Это идет по всему. Это показывает, как именно поместить токен csrf (в шаблон):

<head> 
    <title>Contact Us</title> 
</head> 
<body> 
    <h1>Contact us</h1> 

{% if form.errors %}
    <p style="color: red;"> 
        Please correct the error{{ form.errors|pluralize }} below.
    </p> 
{% endif %}

<form action="" method="post"> 
    {% csrf_token %}
    <ul> 
        {{ form.as_ul }}
    </ul> 
    <input type="submit" value="Submit"> 
</form> 
</body> 

Кроме того, измените значение для отправки вместо сохранения, а вместо / сохранить / для действия используйте сообщение ....., которое может заставить его работать.

...