AJAX POST在Django视图中未通过XMLHttpRequest检查

0 投票
1 回答
1644 浏览
提问于 2025-04-16 12:10

我有一个简单的HTML页面,上面有几个几乎一模一样的表单,用户可以填写并提交。提交后,页面会把数据添加到数据库中,然后重新生成一份稍微更新过的表单列表,再把这些表单发回浏览器('/route/complete/' 对应的是urls.py中的add_completed_route_view)。

第一次提交的时候一切都很顺利。但是,当页面用新的表单列表重新绘制后,下一次提交就会在我设置的request.is_ajax()测试中失败。这导致程序跳过了request.REQUEST['next'],直接转到home_view。

我在下面注释掉了这部分代码,但我也尝试过在视图中添加c['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest',但这并没有解决问题。

我希望能找到帮助,确保在用户通过AJAX提交时,头信息中能继续包含正确的XMLHttpRequest参数。代码在下面,非常感谢大家的帮助。

script.js

<script>
$(document).ready(function() {
  $(".doneForm").submit(function() {
    var route_id = $(this).find('input[name=route_id]').val()
    var next = $(this).find('input[name=next]').val()
    var reqData = {route_id:route_id,next:next}


    $.ajax({
      type: "post",
      url: "/route/complete/",
      data: reqData,
      success: function(data) {
        $("#routeTable").html(data);
      }
    });
  return false;
  });
});
</script> 

还有

template.html

<div id="routeTable">
  {% for route in route_list %}
  <div id="routeDone">
    <form class="doneForm" action="/route/complete/" method="post">
      <input type="hidden" name="route_id" value="{{ route.route_id }}" />
      <input type="hidden" name="next" value="{{ request.get_full_path }}" />
      <input type="submit" value="Done" class="doneButton" />
    </form>
  </div>
  {% endfor %}
</div>

还有

views.py

def add_completed_route_view(request):
    if request.method == 'POST' and request.user.is_authenticated():
        add_completed_route(request)
        if request.is_ajax():
            wall_slug = get_wall_slug_from_route_id(request.REQUEST['route_id'])
            c = get_context_for_wall_page(request, wall_slug)
            # c['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
            return render_to_response('m/js_route_table.html', c, context_instance=RequestContext(request))
        else:
            return HttpResponseRedirect(request.REQUEST['next'])
    else:
        return HttpResponseRedirect(reverse('home_view'))

1 个回答

3

问题在于,一旦Ajax请求完成,它会用一个新的表单替换掉原来的表单,而这个新表单就没有绑定javascript事件处理器了。所以下次表单通过正常的POST方法提交时,就不会触发相关的事件。

幸运的是,jQuery提供了几个方法可以帮你解决这个问题,比如livedelegate。所以,不要使用$(".doneForm").submit(function() ...,而是这样做:

$(".doneForm").live("submit", function() {...

撰写回答