【问题标题】:Form submitted twice in Chrome/Safari在 Chrome/Safari 中提交了两次表单
【发布时间】:2011-03-12 07:22:38
【问题描述】:

我正在寻求执行基本表单发布,但以下内容在 Chrome 和 Safari 中两次提交到服务器(但在 Firefox 中的行为与预期相同):

<form id="create-deck-form" action="/decks/create" method="post">
  <fieldset>
    <legend>Create new deck</legend>
    <label for="deck-name-field">Name</label>
    <input id="deck-name-field" name="deck-name-field" type="text" value="" maxlength="140" />

    <label for="tag-field">Tags</label>
    <input id="tag-field" name="tag-field" type="text" value="" maxlength="140" />

    <input class="add-button" type="submit" value="Create" />
  </fieldset>
</form>

我想在提交前使用onsubmit属性对字段进行验证,但是无论返回值为true,表单都会提交两次。

我试图将 jQuery 处理程序绑定到表单,但在这里,默认行为不会被阻止,表单被提交两次,例如:

<script type="text/javascript">
 $(document).ready(function() {
     $("#create-deck-form").submit(function(event){
          if($("#deck-name-field").val() == "") {
            event.preventDefault();
            alert("deck name required");
          }
        });
 });
</script>

虽然我认为这对新的眼睛来说有些明显的错误,但我很困惑为什么提交,无论是否经过验证,都会在 Chrome 和 Safari 中向服务器发送重复的帖子。如有任何见解,我将不胜感激。

【问题讨论】:

  • 还有其他的吗?例如,是否有任何“点击”处理程序在表单上显式调用“submit()”?
  • 谢谢,尖尖的。不,目前它只是简单的框架,没有其他处理程序绑定到表单或其按钮。
  • 我越想越觉得奇怪。我不知道如果我希望让表单发布两次(当然,无需将表单连接到 AJAX 提交机制)。
  • @meg 页面正在导入的某些 Javascript 文件是否可能会将某些内容附加到表单或按钮上,或者其他什么?您能否(实验性地)尝试省略一些脚本文件以查看是否有所作为?当然,目前尚不清楚为什么这会导致 Chrome 和 FF 之间的行为不同,但这无论如何都是一个奇怪的问题。
  • @Pointy!我撕掉了所有连接的 JS 和一些东西,某处正在对我的表单做一些事情,不请自来!当它滚动时我会告诉你的。我只是知道这是非常愚蠢的事情;)

标签: jquery forms cross-browser facebox double-submit-problem


【解决方案1】:

您可以在收到警报后尝试return false; 并删除event.preventDefault();。也许您的 else 子句中还需要 return true;。我相信我在某个地方有这样的工作。

【讨论】:

  • 谢谢你,科恩。在验证失败的情况下,行为都很好(是的,或者 event.preventDefault(); 或返回 false;按预期执行)。只要验证通过,表单就会提交两次。在这种情况下,默认行为被显式调用(使用 else 子句返回 true)或通过不阻止默认行为/返回 false 来隐式调用(如上面的代码 sn-ps)。
  • 您是否尝试过使用非匿名方法(用名称定义)并将其用作属性,例如:
    。如果这也发布了两次,则问题出在您的代码中的其他地方...
  • @Koen 确实做到了,谢谢。导致问题的不是表单提交,而是可能从哪里开始。
【解决方案2】:

我不是 100% 确定,但请试试这个:

<script type="text/javascript">
   $(document).ready(function() {
      $("#create-deck-form").submit(function(event){
         if(!$("#deck-name-field").val().length) {
           return false;
         }
       });
   });
</script>

如果不行,请查看

for(e in $("#create-deck-form").data('events'))
    alert(e);

这将提醒您绑定到您的form 的所有事件。也许有更多的事件处理程序?否则也会提醒/记录

$("#create-deck-form").attr('onclick')

$("#create-deck-form").attr('onsubmit')

以防万一。

【讨论】:

  • 是的,很确定你需要返回 false 来阻止浏览器默认事件的发生
  • 谢谢安迪和汤姆。我想我可能因为提到验证而混淆了这个问题。如果验证失败,我很好(event.preventDefault 相当于 return false 并且两者都很好),当表单提交时没有验证问题时我会遇到麻烦。因此,正如我在上面的第一个代码 sn-p 中所示,没有验证或 JS 参与的基本表单提交两次提交到服务器。关于检查与表单关联的任何流氓处理程序的好主意,安迪,我会试一试。
  • @meg:不完全是,从事件处理程序返回false 会触发preventDefault 加上stopPropagation
  • @Andy,我可以确认没有意外的处理程序绑定到表单。 @jAndy,我明白了!非常感谢。不过,不确定这对我当前的问题有何帮助。在我的情况下,当验证通过时,我得到了意外的行为,因此既没有阻止默认行为的代码也没有返回 false。
【解决方案3】:

好的,不确定这有多大帮助,但请尝试删除提交输入并通过 javascript 提交表单。比如

<input id="submit-button" class="add-button" type="button" value="Create" />

那你就不用听onsubmit了,可以试试

$('#submit-button').click(function(evt) {
    if(validationSuccess(...)) {
        $("#create-deck-form").submit();
    } else {
        //display whatever
    }
});

现在您的方式也应该可以工作...但是这样您就可以调试问题所在的位置......这应该只提交一次...祝您好运!

【讨论】:

  • 感谢 JavaDrinker,我确实尝试过这种方法,但无济于事。我一直在挖掘,它可能在我的应用程序中更深层次。我希望今天解决并发布解决方案。
  • 这可能是一个愚蠢的问题,但是:您如何确定您的表单被提交了两次?我的意思是,这个“双重提交”的结果是什么?
  • 我可以在控制台打印中看到有两个对服务器的请求,并且在数据存储中可以看到第二个卡片组。原来不是表单提交,而是行为可以开始的地方 - 红鲱鱼!
【解决方案4】:

这个问题实际上与 Facebox (http://defunkt.github.com/facebox/) 有关。页面加载后,Facebox 初始化会引发第二组请求。因此,如果您发布到/myaction/create,Facebox 将启动第二组请求,并将基本 URL 设置为/myaction/create。解决方法是在发布后重定向到处理获取请求的 URL,这样您就不会最终执行两次发布。非常感谢您的帮助。

【讨论】:

  • 我好像也有同样的问题,你有解决方案的代码(或全局描述)吗,你是如何在发帖后重定向get的?
猜你喜欢
  • 2015-09-03
  • 2011-06-17
  • 2011-11-16
  • 2012-05-06
  • 1970-01-01
  • 2019-11-11
  • 1970-01-01
  • 2013-03-27
  • 2014-11-03
相关资源
最近更新 更多