Django jQuery post请求

8
$.ajax({
    url:'/',
    type: "POST",
    data: {name: 'name', age: 'age'},
    success:function(response){},
    complete:function(){},
    error:function (xhr, textStatus, thrownError){}
});

在views.py中:

class SomeView(generic_views.TemplateView):
    template_name = 'something.html'

    def get(self, request, *args, **kwargs):
        ...something...
        return self.render_to_response(context)

    def post(self, request, *args, **kwargs):
        name = request.POST['name']
        age = request.POST['age']
        ...something...

我得到的结果是:[05/Oct/2012 12:03:58] "POST /something/ HTTP/1.1" 403 2294

我想通过jQuery将这些数据(姓名和年龄)发送到“SomeView”中的此post函数。这与加载的模板相同,只是请求类型不同。在get()上加载模板,在post()上应调用post()函数。这可能吗?我已经检查了其他问题并得到了此解决方案。它应该可以工作。我做错了什么?

4个回答

12
你所做的错误并不多。Django在收到POST请求时,如果Csrf检查失败,会返回403响应(禁止)。你可以通过jQuery的ajaxSetup来实现这一点。代码段可以在这里找到。
但是,这种方法只适用于POST请求而不适用于GET请求,因为csrf中间件不会检查GET请求。
另外,考虑使用基于类的表单,尤其是在创建/编辑/删除模型实例的表单中。可以使用ModelForms和CreateViews。它们可以处理参数验证和get/post请求。这些泛化的类视图可能需要一些时间来掌握,但非常值得学习。

是的,在其他网站上我使用FormView。但在这种情况下,我不能这样做(长话短说)。 现在事情已经解决了,但在终端上我看到 [05/Oct/2012 15:08:11] "POST /something/ HTTP/1.1" 500 9499 - premik91
500只是一个服务器错误。这可能是由于您的POST方法中出现任何Python错误引起的。 - A.J.Rouvoet
是的,但不是以你能看到的方式。堆栈跟踪和其他Django调试信息将作为HttpResponse返回到您的ajax请求中。您可以通过在jquery.ajax错误回调中记录响应来记录它。使用Firebug / Chrome开发人员工具查看发生了什么可能更容易。这些工具将向您提供传递给服务的确切参数以及服务器的响应,这将是Django调试信息。 - A.J.Rouvoet
我也成功解决了那个错误。我只需要在post()函数的结尾添加"return self.render_to_response({})"即可。 - premik91

10

你需要在ajax调用中包含一个CSRF(跨站请求伪造)令牌。具体文档可以参考这里:https://docs.djangoproject.com/en/dev/ref/contrib/csrf/

或者,如果你想使用一个快速解决方案,可以为你的视图使用@csrf_exempt装饰器:

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def my_view(request):
   ...

为视图添加@csrf_exempt装饰器是一个快速修复的方法,而且非常有趣。 - Tharusha
感谢豁免。显然,99%的情况下不想在生产环境中使用,但是在开发中,我不想花时间设置它,并且希望能够开始实际原型设计。 - logicOnAbstractions

4
在Django模板中,您可以添加以下内容...
{% csrf_token %}

将会把以下内容输出到你的页面html中...
<input type="hidden" name="csrfmiddlewaretoken" value="ckhUdNOTj88A...hfTnREALlks2kz">

然后,使用 JavaScript,您可以简单地查找此输入并获取其值 - 例如,以下非 jQuery 示例...
var el = document.getElementsByName("csrfmiddlewaretoken");
csrf_value = el[0].getAttribute("value");

最后在您的jQuery AJAX提交表单数据行中添加csrf_value,代码如下...
data: {name: 'name', age: 'age', csrfmiddlewaretoken: csrf_value},

这是一个可行的jsFiddle概念示例:https://jsfiddle.net/vdx1Lfpc/18/

1

我在另一个帖子上看到,你可以像这样做:

$.ajax({
    method: "POST",
    url: "{% url 'some_route' %}",
    headers: {'X-CSRFToken': '{{ csrf_token }}'},
    contentType: "application/json",
    dataType: 'json',
    data: {name:$('#id_name').val()}
})
.fail(function(message) {
    alert('error');
})
.done(function(data) {
    alert(data);
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接