【问题标题】:Django Posts Not Working:Django帖子不起作用:
【发布时间】:2011-04-17 21:27:24
【问题描述】:

我正在使用 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 表单清理这些数据,并且发布请求似乎没有发送到服务器(仅在生产中)。

我做错了什么?

更新:

解决方案:从 django 1.3 开始,crsf 令牌需要推送 ajax 发布请求(而不是获取)

另外,根据下面提供的链接,以下 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 之间发生变化?? 无论如何,它有效。感谢大家的帮助

【问题讨论】:

  • 使用 firebug 或 webkit 的检查器查看请求发生了什么,我敢打赌那里有 500 错误。
  • 实际上我得到了 403 禁止
  • ...登录的用户是否正在尝试发送该 ajax 表单?
  • 我还没有任何用户认证系统

标签: ajax django jquery


【解决方案1】:

您可以直接从生产服务器访问您的 javascript 文件吗?您在生产中使用哪个 Django 版本?如果您在生产中使用 1.2.5+,则需要在 AJAX 发布操作期间将 csrf 令牌推送到服务器。

the release notes in 1.2.5CSRF

检查你的 Django 版本:

import django
django.get_version()

在您的生产站点或生产服务器的 shell 中打印上述内容,同时确保您使用的是正确的 Python 路径。

【讨论】:

  • $ python -c "import django; print django.get_version()" 1.3
  • 好的,所以解决方案实际上是 CSRF 令牌没有被 ajax 请求推送。我必须进行的一项修改如下(取自 1.2.5 发行说明中提供的链接
  • 看起来您在生产中使用的是 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})

实际上,将上面的代码与您的代码进行比较,您可能需要在您的 django 视图中设置 content_type 以便 jQuery 能够理解和处理响应。请注意,上面使用的是 django 1.3 基于类的视图,但无论如何逻辑都应该很熟悉。如果表单处理通过或失败,我使用context.success 发出信号 - 因为任何类型的有效响应 (json) 都会向 jQuery.post 发出请求成功的信号。

【讨论】:

  • 在我的 HttResponse 中添加了 content_type="application/json", mimetype='application/json',但没有骰子
猜你喜欢
  • 2015-01-09
  • 1970-01-01
  • 2018-12-15
  • 2018-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多