如何在Django中使用jQuery/Ajax进行POST请求?

20
我正在尝试在Django中使用jQuery/AJAX发送POST数据,但遇到了问题。当我运行下面的代码并点击“test”按钮时,整个页面会重新加载,这不是我想要发生的事情(这就是为什么我使用AJAX的原因)。
我也无法确认AJAX请求是否到达Django视图。
编辑:我已经进行了返回false和event.preventDefault()的编辑。新页面没有加载,但我仍然看不到< div id ='message'>字段中更新的文本。我不确定数据是否被发送。我在控制台中看到:
POST /edit_favorites/ HTTP/1.1" 403 2294

views.py:

from django.shortcuts import render_to_response
from django.http import HttpResponse

def edit_favorites(request):
    if request.is_ajax():
        message = "Yes, AJAX!"
    else:
        message = "Not Ajax"
    return HttpResponse(message)

urls.py:

url(r'^edit_favorites/', 'edit_favorites'),

HTML:
<form method='post' id='test'>
  <input type="hidden" value="video34"/>
  <input type='submit' value='Test button'/>
  <div id='message'>Initial text</div>
</form>

JavaScript:
$(document).ready(function () {
  $("#test").submit(function (event) {
    event.preventDefault();
    $.ajax({
      type: "POST",
      url: "/edit_favorites/",
      data: {
        'video': $('#test').val() // from form
      },
      success: function () {
        $('#message').html("<h2>Contact Form Submitted!</h2>")
      }
    });
    return false;
  });
});

任何建议吗?

在视图中添加断点,视图代码是否在运行?在 AJAX 成功处理程序中添加断点,它是否在运行?添加 AJAX 错误处理程序,在那里设置断点,它是否在运行?还有两个随机的副笔记:你可以使用 $('#test').serializeArray(),建议只捕获你想要的 URL:url(r'^edit_favorites/$', ...(没有 $,你会捕获任何以此开头的 URL)。 - dokkaebi
3个回答

16

放错了位置的 return false;。它应该在 .submit() 函数的末尾,所以把它往上移一行:

$(document).ready(function () {
  $("#test").submit(function (event) {
    $.ajax({
      type: "POST",
      url: "/edit_favorites/",
      data: {
        'video': $('#test').val() // from form
      },
      success: function () {
        $('#message').html("<h2>Contact Form Submitted!</h2>")
      }
    });
    return false; //<---- move it here
  });

});

更新:

关于POST /edit_favorites/ HTTP/1.1" 403 2294的问题,请查看此帖子,它与您的问题相似:


我已经编辑了return false和event.preventDefault()。新页面不会加载,但我仍然无法在div id ='message'字段中看到更新后的文本。我不确定数据是否被发送。 - sharataka
@sharataka 看看这个,https://dev59.com/5WnWa4cB1Zd3GeqPyTyk - Muthu Kumaran
我相信这是因为这是我在urlconf中设置的。 - sharataka
4
看起来,你需要在ajax调用中包含CSRF(跨站点请求伪造)令牌。 - Muthu Kumaran
@MuthuKumaran - 我知道可以将ajax POST请求发送到与最初呈现表单时使用的不同视图。 为此,我尝试了函数视图来发布表单数据(序列化),但是数据无法发布到数据库中。 我可以在控制台中看到表单数据已序列化,但无法将其POST到数据库中。 您能否指向一个最小的示例,只需执行我正在尝试实现的内容? - Love Putin Not War

6
以下方法对我有效,希望也能帮到你。
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse

@csrf_exempt
def edit_favorites(request):
    if request.is_ajax():
        message = "Yes, AJAX!"
    else:
        message = "Not Ajax"
    return HttpResponse(message)

JsonResponse与HttpResponse相比有什么要求吗? - Lord-shiv

4
这里发生的情况是当您提交一个HTML表单时,它会将表单数据发送到<form>action属性。在您的javascript中,您订阅表单的submit事件,然而您从未禁用表单的默认行为,即遵循action属性。在jQuery中,您可以调用事件参数上的preventDefault方法来修改该行为,并返回false(如果您调用preventDefault,则返回false是不必要的,但最好确定一下...):
$(...).submit(function(e) {
    e.preventDefault();
    ...
    return false;
});

编辑

关于错误,您的错误信息不太有帮助,但我猜测您没有验证CSRF。更详细的解释可以在这里找到。然而,快速修复方法是将此文件与您的jQuery一起包含,并在您的视图中添加ensure_csrf_cookie装饰器。


我已经编辑了return false和event.preventDefault()。新页面不会加载,但我仍然无法在div id ='message'字段中看到更新后的文本。我不确定数据是否被发送。 - sharataka
文本是否更新为<h2>联系表单已提交!</h2>?在Firebug中是否有任何错误? - miki725
我没有使用Firebug,但我在控制台中看到“POST /edit_favorites/ HTTP/1.1” 403 2294 ……这有助于故障排除吗? - sharataka
不是很确定,但我对CSRF有一种预感。请检查答案中的编辑。 - miki725

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