表单在 2 次 ajax 更新后无法发送 POST 请求

Posted

技术标签:

【中文标题】表单在 2 次 ajax 更新后无法发送 POST 请求【英文标题】:Form loses ability to send POST requests after 2 ajax updates 【发布时间】:2011-05-02 11:49:42 【问题描述】:

我有一个包含对象的表单:

<form method="post" class="object_form" id="event-core-form" action="% url save_event_core_data event.id %" enctype="multipart/form-data">
     form.as_p 
    <p>
        <input class="object-submit" id="object-data-save" type="submit" value="Save data">
    </p>
</form>

点击“提交”按钮后,我正在运行此脚本,该脚本通过 ajax 提交我的表单、更新数据并返回更新后的表单,该表单将被插入到原来的位置:

$("#object-data-save").livequery("click", function(e) 
    e.preventDefault();
    $(this).parents("form:first").ajaxSubmit(
        data: "action": action,
        "success": function(data) 
            data = JSON.parse(data);
            $("#core-data").html(data["html"]);
            $("#message").show();
            $("#message").fadeIn(400).html('<span>'+data["message"]+'</span>');
            setTimeout(function()
                $("#message").fadeOut("slow", function () 
                    $("#message").hide();
                );

            , 1500);                
        
    );
    return false;
);

这会运行以下函数:

def event_core_data(request, event_id):
    template_name="management/core_event.html"    
    event = Event.objects.get(pk=event_id)
    form = EventForm()

    if request.method == "POST":
        form = EventForm(instance=event, data=request.POST)
        message = _("Error saving data")
        if form.is_valid():
            form.save()
            message = _(u"Data saved.")

        html =  render_to_string(template_name, RequestContext(request, 
            "form" : form,
            "event" : event,
        ))

        result = simplejson.dumps(
            "html" : html,
            "message" : message,
        , cls = LazyEncoder)

        result = HttpResponse(result)
        logging.debug(result)
    else:
        form = EventForm(instance=event)
        result = ""
        try:
            result = render_to_string(template_name, RequestContext(request, 
                "form" : form,
                "event" : event,
            ))
        except:
            pass

    return result

保存后一切都按预期工作。但是在第三次更新后,我的表单没有插入到父模板中。相反,我被重定向到编辑函数的 url,并且表单呈现为原始 html。另外,我在萤火虫中注意到,当我被重定向时 - 没有发送 POST 并且我的 javascript 中的虚拟“警报”没有被触发。 这是显示初始状态的函数(如果有帮助的话):

def manage_event(request, event_id,):
    template_name = 'management/edit_event.html'

    try:
        event = Event.objects.get(pk=event_id)
    except DoesNotExist:
        url = reverse("manage_events")
        return HttpResponseRedirect(url)

    return render_to_response(template_name, RequestContext(request, 
        "core_data" : event_core_data(request, event_id),
        "event" : event,
    ))

编辑

这是此项目的测试链接,您可以在其中查看正在发生的事情。 'event_core_data' 在成功更新后将 request.POST 返回到控制台。

http://ntt.vipserv.org/manage/events/2

我也想知道为什么我的日期选择器小部件在提交后消失了。这些东西是否以某种方式联系在一起?


编辑 2

我已经尝试使用 .post 或 .ajax 代替 .ajaxSubmit 但没有任何运气。

【问题讨论】:

因此,由于某种原因,在第二次更新表格后不再作为邮件发送。这怎么可能,有什么想法吗? 我强烈推荐使用 1) Firefox,2) Firebug。启用 Firebug,然后重新加载页面。查看控制台以查看确切服务器返回的内容。断点也很有用。 id='object-data-save" 别告诉我noobdy知道如何解决这个问题... :( 【参考方案1】:

首先,你正在做一些有点奇怪的事情。您使用一个 jQuery 插件,它应该通过 ajax 处理表单提交并重新填充字段。尽管如此,在成功时,您将表单的所有 HTML 替换为来自服务器的 HTML,从而否定它的工作。

这会破坏您的日历/时间小部件,因为您在页面加载时初始化小部件,告诉它们对某些页面元素采取行动,您稍后会替换这些元素。

但这本身并不会破坏表单提交。

首先,如果您停止替换表单 HTML,则不需要插件来“实时”附加事件。其次,无论如何,您实际上并不需要插件,因为 jQuery 中的内置 live() 方法似乎应该可以完成这项工作(也就是说,如果您确实需要此功能)。第三,如果您使用插件并且它们似乎无法正常工作,请更新到最新版本。您使用的版本不支持 jQuery 中的 html() 方法。

livequery-plugin 通过覆盖任何可能更新 DOM 的 jQuery 方法来发挥它的魔力。因此,当程序员调用 f.ex、append() 时,它会拦截调用,为您调用 append(),然后检查文档中是否存在与您提供的选择器匹配的新元素或消失的元素。您使用的版本不知道html(),因此不会拦截它。

因此,当您在页面加载时启动 DOM 检查时,它会第一次起作用。当返回该结果时,该事件实际上附加到新的提交按钮,因为调用 html() 设置新表单和完成消息在内部调用拦截的方法。因此,第二次提交按预期工作。但是当第二次调用返回时,内部使用了一个 jQuery 缓存,没有调用任何拦截的方法。因此该事件不会附加到提交按钮,使其充当常规表单提交按钮。

要解决此问题,如果没有明显的需要,请停止使用实时附加来监听事件。如果有,请使用内置插件或至少更新您的 livequery 插件。另外,不要替换整个表单 HTML。同样,如果有不明显的原因,请在每次设置 HTML 后重新初始化日历小部件。

【讨论】:

我以为 ajaxSubmit 只是从表单中获取数据。谢谢!

以上是关于表单在 2 次 ajax 更新后无法发送 POST 请求的主要内容,如果未能解决你的问题,请参考以下文章

ajax中,发送请求的类型

如何通过ajax从表单发送POST数据数组?

前端与后端的数据交互(jquery ajax+python flask)

通过表单发送 AJAX 数据的最佳实践 - 取回值

JS——AJAX

从表单收集数据,在对象中堆叠并使用 Vue 使用 AJAX 发送