#ajax #django #jquery
#ajax #django #jquery
Вопрос:
Я использую Django 1.2.3 для разработки сайта. Мои запросы ajax get работают нормально, но запросы post работают в режиме разработки (127.0.0.1: 8000), но не тогда, когда я запускаю сайт в рабочую среду с использованием apache nginx.
Вот пример
urls.py:
(r'api/newdoc/$', 'mysite.documents.views.newdoc'),
views.py
def newdoc(request):
# only process POST request
if request.is_ajax():
data= dict(request.POST)
# save data to db
return HttpResponse(simplejson.dumps([True]))
в javascript:
$.post("/api/newdoc/", {data : mydata}, function(data) { alert(data);}, "json");
мое оповещение никогда не вызывается …. это проблема, потому что я хочу очистить эти данные через форму django, и запросы post, похоже, не попадают на сервер (только в рабочей среде).
что я делаю не так?
Обновления:
решение: токены crsf необходимо отправлять в запросы ajax post (а не получать) начиная с django 1.3
кроме того, согласно приведенной ниже ссылке, следующий javascript
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-CSRFToken",
$("#csrfmiddlewaretoken").val());
}
}
});
необходимо изменить следующим образом:
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-CSRFToken",
$('input[name="csrfmiddlewaretoken"]').val());
}
}
});
способ отображения токена csrf в форме, должно быть, изменился в диапазоне 1.25 — 1.3??
несмотря на это, это работает. всем спасибо за вашу помощь
Комментарии:
1. Используйте firebug или webkit’s inspector, чтобы посмотреть, что происходит с запросом, бьюсь об заклад, там ошибка 500.
2. на самом деле я получаю 403 запрещенных
3. … зарегистрировался ли пользователь, который пытается отправить эту форму ajax?
4. у меня пока нет никакой системы аутентификации пользователя
Ответ №1:
Можете ли вы напрямую получить доступ к своим файлам javascript с производственного сервера? Какую версию Django вы используете в рабочей среде? Если вы используете 1.2.5 в рабочей среде, вам нужно будет отправить токен csrf на сервер во время операции публикации AJAX.
Смотрите примечания к выпуску в 1.2.5 и CSRF
Чтобы проверить вашу версию Django:
import django
django.get_version()
Распечатайте приведенное выше на вашем производственном сайте или из оболочки вашего производственного сервера, убедившись, что вы используете правильный путь Python.
Комментарии:
1. $ python -c «импортируйте django; распечатайте django.get_version()» 1.3
2. итак, решение фактически заключалось в том, что токен CSRF не отправлялся с запросом ajax. одно изменение, которое мне пришлось внести, было следующим (взято по ссылке, приведенной в примечаниях к выпуску 1.2.5
3. Похоже, вы используете 1.3 в рабочей среде. Создайте новый virtualenv на своем компьютере разработчика и установите django 1.3. Запустите свой проект оттуда и протестируйте работу post ajax. Возможно, вам потребуется прочитать больше по ссылке CSRF, которую я разместил выше.
Ответ №2:
При беглом взгляде ваш код выглядит нормально, но я покажу вам пример моего кода обработки форм ajax в надежде, что это поможет разобраться в возникшей ошибке. Хотя то, что прокомментировал @dmitry, должно быть вашим первым шагом отладки — используйте firebug или инспектор, чтобы увидеть, возвращает ли вызов ajax ошибку.
// js (jQuery 1.5)
$(form).submit(function(event) {
event.preventDefault();
$.post(post_url, $(form).serialize())
.success(function(data, status, jqxhr) {
if (data.success) { // form was valid
$(form)
// other irrelevant code
.siblings('span')
.removeClass('error')
.html('Form Successful');
} else { // form was invalid
$(form).siblings('span').addClass('error').html('Error Occurred');
}
})
.error(function(jqxhr, status, error) { // server error
$(form).siblings('span').addClass('error').html("Error: " error);
});
});
// django
class AjaxFormView(FormView):
def ajax_response(self, context, success=True):
html = render_to_string(self.template_name, context)
response = simplejson.dumps({'success': success, 'html': html})
return HttpResponse(response, content_type="application/json", mimetype='application/json')
// view deriving from AjaxFormView
def form_valid(self, form):
registration = form.save()
if self.request.is_ajax():
context = {'competition': registration.competition }
return self.ajax_response(context, success=True)
return HttpResponseRedirect(registration.competition.get_absolute_url())
def form_invalid(self, form):
if self.request.is_ajax():
context = { 'errors': 'Error Occurred'}
return self.ajax_response(context, success=False)
return render_to_response(self.template_name, {'errors':form.errors})
На самом деле, сравнивая приведенное выше с вашим кодом, вам, возможно, потребуется установить content_type в вашем представлении django, чтобы jQuery мог понять и обработать ответ. Обратите внимание, что в приведенном выше примере используются представления на основе классов django 1.3, но логика должна быть знакома независимо от этого. Я использую context.success
для сигнализации о том, прошла ли обработка формы или произошел сбой — поскольку действительный ответ (json) любого вида будет сигнализировать о том, jQuery.post
что запрос был успешным.
Комментарии:
1. добавлено content_type=»application / json», mimetype = ‘application / json’ в мой HttResponse, хотя без кубиков