2013-10-12 4 views
26

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

<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!') 

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

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

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

Edit-1

Я не был якобы передавая csrf маркера вместе с моим почтовым запросом. SO согласно документации, которую я добавил следующий код в шаблон 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 в консоли, предполагая, что куки не установлен или не определен , Что мне не хватает?

ответ

35

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

+0

Я обновил свой вопрос согласно вашему предложению. Я все равно получаю ту же ошибку. Буду признателен, если вы скажете мне, как вы его работаете. – Annihilator8080

+0

«csrfmiddlewaretoken» - это ключ к вашим опубликованным данным, например, когда вам нужно войти в аккаунт ajax, ваши опубликованные данные могут выглядеть так: {'username': 'username', 'password': 'password', 'csrfmiddlewaretoken': 'CSRF-TOKEN-VALUE'} – Yohn

+0

Спасибо @PYTY, это была проблема. Я не вставлял токен. – Annihilator8080

2

Чтобы установить куки, используйте ensure_csrf_cookie декоратора на ваш взгляд:

from django.views.decorators.csrf import ensure_csrf_cookie 

@ensure_csrf_cookie 
def hello(request): 
    code_here() 
+0

И у вас есть middleware '' django.middleware.csrf.CsrfViewMiddleware'', в MIDDLEWARE_CLASSES в ваших настройках.py'? – kelvinss

+0

Да, @kelvinss, я внесла необходимые изменения в settings.py – Annihilator8080

18

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

Первая загрузка печенья: 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!"); 
    } 

}) 
+0

Я следил за приведенным выше кодом, и теперь я могу отправить сообщение ajax(), но он не читает мои данные/параметры. Пример данных: {"name": "John Birada"}. Параметр name всегда равен нулю. спасибо –

0

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

4

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

403 запрещено ответ приходит от CSRF промежуточного слоя (см Cross Site Request Forgery protection):

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

Доступно множество опций. Я бы рекомендовал следовать за answer of @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 установлено значение ИСТИНА, что часто бывает, как Security middleware рекомендует так, то печенье не существует, даже если @ensure_csrf_cookie() является используемый. В этом случае {% csrf_token %} должен быть предоставлен в каждом виде, который производит выход, такой как <input name="csrfmiddlewaretoken" value="cr6O9...FUXf6" type="hidden">. Таким образом, переменная csrfToken просто быть получено с:

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

Опять $.ajaxSetup потребовалось бы, конечно.

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

+1

Наконец выяснил, что происходило в вашем комментарии. Они обязательно должны добавить это в документы csrf ajax. Я понятия не имел, что 'CSRF_COOKIE_HTTPONLY' нарушает мои сообщения ajax. – Airith

-3

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

1

Try включая этот декоратор на код отправки

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) 
0

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

Wtower сводка прекрасна, и я думал, что это сработает после удаления CSRF_COOKIE_HTTPONLY с settings.py, но это doesnt в https!

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

Вместо того, чтобы

"django_language = пт; csrftoken = rDrGI5cp98MnooPIsygWIF76vuYTkDIt"

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

"django_language = Fr"

ПОЧЕМУ ? Например, SSL/https removes X-CSRFToken from headers Я думал, что это связано с параметрами прокси-сервера Nginx, но, по-видимому, нет ... Любая идея?

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

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

В этом случае можно передать его АЯКС либо заголовка (xhr.setRequestHeader), либо по params.

Смежные вопросы